Completed
Pull Request — master (#857)
by Maxime
02:14
created

StubCustomRepository::getClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\Tests\Repository;
4
5
use Doctrine\Bundle\DoctrineBundle\Repository\ContainerRepositoryFactory;
6
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
7
use Doctrine\Common\Persistence\ObjectRepository;
8
use Doctrine\ORM\Configuration;
9
use Doctrine\ORM\EntityManagerInterface;
10
use Doctrine\ORM\EntityRepository;
11
use Doctrine\ORM\Mapping\ClassMetadata;
12
use PHPUnit\Framework\TestCase;
13
use Psr\Container\ContainerInterface;
14
15
class ContainerRepositoryFactoryTest extends TestCase
16
{
17
    public function testGetRepositoryReturnsService()
18
    {
19
        if (! interface_exists(ContainerInterface::class)) {
20
            $this->markTestSkipped('Symfony 3.3 is needed for this feature.');
21
        }
22
23
        $em        = $this->createEntityManager(['Foo\CoolEntity' => 'my_repo']);
24
        $repo      = new StubRepository($em, new ClassMetadata(''));
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
25
        $container = $this->createContainer(['my_repo' => $repo]);
26
27
        $factory = new ContainerRepositoryFactory($container);
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
28
        $this->assertSame($repo, $factory->getRepository($em, 'Foo\CoolEntity'));
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
29
    }
30
31
    public function testGetRepositoryReturnsEntityRepository()
32
    {
33
        if (! interface_exists(ContainerInterface::class)) {
34
            $this->markTestSkipped('Symfony 3.3 is needed for this feature.');
35
        }
36
37
        $container = $this->createContainer([]);
38
        $em        = $this->createEntityManager(['Foo\BoringEntity' => null]);
39
40
        $factory    = new ContainerRepositoryFactory($container);
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
41
        $actualRepo = $factory->getRepository($em, 'Foo\BoringEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
42
        $this->assertInstanceOf(EntityRepository::class, $actualRepo);
43
        // test the same instance is returned
44
        $this->assertSame($actualRepo, $factory->getRepository($em, 'Foo\BoringEntity'));
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
45
    }
46
47
    public function testCustomRepositoryIsReturned()
48
    {
49
        if (! interface_exists(ContainerInterface::class)) {
50
            $this->markTestSkipped('Symfony 3.3 is needed for this feature.');
51
        }
52
53
        $container = $this->createContainer([]);
54
        $em        = $this->createEntityManager([
55
            'Foo\CustomNormalRepoEntity' => StubRepository::class,
56
        ]);
57
58
        $factory    = new ContainerRepositoryFactory($container);
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
59
        $actualRepo = $factory->getRepository($em, 'Foo\CustomNormalRepoEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
60
        $this->assertInstanceOf(StubRepository::class, $actualRepo);
61
        // test the same instance is returned
62
        $this->assertSame($actualRepo, $factory->getRepository($em, 'Foo\CustomNormalRepoEntity'));
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
63
    }
64
65
    /**
66
     * @expectedException \RuntimeException
67
     * @expectedExceptionMessage The service "my_repo" must implement ObjectRepository (or extend a base class, like ServiceEntityRepository).
68
     */
69
    public function testServiceRepositoriesMustExtendObjectRepository()
70
    {
71
        if (! interface_exists(ContainerInterface::class)) {
72
            $this->markTestSkipped('Symfony 3.3 is needed for this feature.');
73
        }
74
75
        $repo = new \stdClass();
76
77
        $container = $this->createContainer(['my_repo' => $repo]);
78
79
        $em = $this->createEntityManager(['Foo\CoolEntity' => 'my_repo']);
80
81
        $factory = new ContainerRepositoryFactory($container);
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
82
        $factory->getRepository($em, 'Foo\CoolEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
83
    }
84
85
    public function testServiceRepositoriesCanNotExtendsEntityRepository()
86
    {
87
        if (! interface_exists(ContainerInterface::class)) {
88
            $this->markTestSkipped('Symfony 3.3 is needed for this feature.');
89
        }
90
91
        $repo = new StubCustomRepository();
92
93
        $container = $this->createContainer(['my_repo' => $repo]);
94
95
        $em = $this->createEntityManager(['Foo\CoolEntity' => 'my_repo']);
96
97
        $factory = new ContainerRepositoryFactory($container);
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
98
        $factory->getRepository($em, 'Foo\CoolEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
99
        $actualRepo = $factory->getRepository($em, 'Foo\CoolEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
100
        $this->assertInstanceOf(StubCustomRepository::class, $actualRepo);
101
    }
102
103
104
    /**
105
     * @expectedException \RuntimeException
106
     * @expectedExceptionMessage The "Doctrine\Bundle\DoctrineBundle\Tests\Repository\StubServiceRepository" entity repository implements "Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface", but its service could not be found. Make sure the service exists and is tagged with "doctrine.repository_service".
107
     */
108
    public function testRepositoryMatchesServiceInterfaceButServiceNotFound()
109
    {
110
        if (! interface_exists(ContainerInterface::class)) {
111
            $this->markTestSkipped('Symfony 3.3 is needed for this feature.');
112
        }
113
114
        $container = $this->createContainer([]);
115
116
        $em = $this->createEntityManager([
117
            'Foo\CoolEntity' => StubServiceRepository::class,
118
        ]);
119
120
        $factory = new ContainerRepositoryFactory($container);
0 ignored issues
show
Documentation introduced by
$container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
121
        $factory->getRepository($em, 'Foo\CoolEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
122
    }
123
124
    /**
125
     * @expectedException \RuntimeException
126
     * @expectedExceptionMessage The "Foo\CoolEntity" entity has a repositoryClass set to "not_a_real_class", but this is not a valid class. Check your class naming. If this is meant to be a service id, make sure this service exists and is tagged with "doctrine.repository_service".
127
     */
128
    public function testCustomRepositoryIsNotAValidClass()
129
    {
130
        if (interface_exists(ContainerInterface::class)) {
131
            $container = $this->createContainer([]);
132
        } else {
133
            // Symfony 3.2 and lower support
134
            $container = null;
135
        }
136
137
        $em = $this->createEntityManager(['Foo\CoolEntity' => 'not_a_real_class']);
138
139
        $factory = new ContainerRepositoryFactory($container);
0 ignored issues
show
Bug introduced by
It seems like $container defined by $this->createContainer(array()) on line 131 can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Doctrine\Bundle\Doctrine...yFactory::__construct() does only seem to accept null|object<Psr\Container\ContainerInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
140
        $factory->getRepository($em, 'Foo\CoolEntity');
0 ignored issues
show
Documentation introduced by
$em is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
141
    }
142
143
    private function createContainer(array $services)
144
    {
145
        $container = $this->getMockBuilder(ContainerInterface::class)->getMock();
146
        $container->expects($this->any())
147
            ->method('has')
148
            ->willReturnCallback(function ($id) use ($services) {
149
                return isset($services[$id]);
150
            });
151
        $container->expects($this->any())
152
            ->method('get')
153
            ->willReturnCallback(function ($id) use ($services) {
154
                return $services[$id];
155
            });
156
157
        return $container;
158
    }
159
160
    private function createEntityManager(array $entityRepositoryClasses)
161
    {
162
        $classMetadatas = [];
163
        foreach ($entityRepositoryClasses as $entityClass => $entityRepositoryClass) {
164
            $metadata                            = new ClassMetadata($entityClass);
165
            $metadata->customRepositoryClassName = $entityRepositoryClass;
166
167
            $classMetadatas[$entityClass] = $metadata;
168
        }
169
170
        $em = $this->getMockBuilder(EntityManagerInterface::class)->getMock();
171
        $em->expects($this->any())
172
            ->method('getClassMetadata')
173
            ->willReturnCallback(function ($class) use ($classMetadatas) {
174
                return $classMetadatas[$class];
175
            });
176
177
        $em->expects($this->any())
178
            ->method('getConfiguration')
179
            ->willReturn(new Configuration());
180
181
        return $em;
182
    }
183
}
184
185
class StubRepository extends EntityRepository
186
{
187
}
188
189
class StubServiceRepository extends EntityRepository implements ServiceEntityRepositoryInterface
190
{
191
}
192
193
class StubCustomRepository implements ObjectRepository
194
{
195
    public function find($id) {}
196
    public function findAll() {}
197
    public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null) {}
198
    public function findOneBy(array $criteria) {}
199
    public function getClassName() {}
200
}
201