Completed
Pull Request — master (#1120)
by
unknown
01:49
created

DoctrineDataCollectorTest::createCollector()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\Tests\DataCollector;
4
5
use Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector;
6
use Doctrine\ORM\Mapping\ClassMetadataInfo;
7
use PHPUnit\Framework\TestCase;
8
use ReflectionClass;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
12
class DoctrineDataCollectorTest extends TestCase
13
{
14
    const FIRST_ENTITY  = 'TestBundle\Test\Entity\Test1';
15
    const SECOND_ENTITY = 'TestBundle\Test\Entity\Test2';
16
17
    public function testCollectEntities()
18
    {
19
        $manager   = $this->getMockBuilder('Doctrine\ORM\EntityManager')->disableOriginalConstructor()->getMock();
20
        $config    = $this->getMockBuilder('Doctrine\ORM\Configuration')->getMock();
21
        $factory   = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory')
22
            ->setMethods(['getLoadedMetadata'])->getMockForAbstractClass();
23
        $collector = $this->createCollector(['default' => $manager]);
24
25
        $manager->expects($this->any())
26
            ->method('getMetadataFactory')
27
            ->will($this->returnValue($factory));
28
        $manager->expects($this->any())
29
            ->method('getConfiguration')
30
            ->will($this->returnValue($config));
31
32
        $config->expects($this->once())
33
            ->method('isSecondLevelCacheEnabled')
34
            ->will($this->returnValue(false));
35
36
        $metadatas = [
37
            $this->createEntityMetadata(self::FIRST_ENTITY),
38
            $this->createEntityMetadata(self::SECOND_ENTITY),
39
            $this->createEntityMetadata(self::FIRST_ENTITY),
40
        ];
41
        $factory->expects($this->once())
42
            ->method('getLoadedMetadata')
43
            ->will($this->returnValue($metadatas));
44
45
        $collector->collect(new Request(), new Response());
46
47
        $entities = $collector->getEntities();
48
        $this->assertArrayHasKey('default', $entities);
49
        $this->assertCount(2, $entities['default']);
50
    }
51
52
    public function testDoNotCollectEntities()
53
    {
54
        $manager   = $this->getMockBuilder('Doctrine\ORM\EntityManager')->disableOriginalConstructor()->getMock();
55
        $config    = $this->getMockBuilder('Doctrine\ORM\Configuration')->getMock();
56
        $factory   = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory')
57
            ->setMethods(['getLoadedMetadata'])->getMockForAbstractClass();
58
        $collector = $this->createCollector(['default' => $manager], false);
59
60
        $manager->expects($this->never())
61
            ->method('getMetadataFactory');
62
        $manager->expects($this->any())
63
            ->method('getConfiguration')
64
            ->will($this->returnValue($config));
65
66
        $config->expects($this->once())
67
            ->method('isSecondLevelCacheEnabled')
68
            ->will($this->returnValue(false));
69
70
        $factory->expects($this->never())
71
            ->method('getLoadedMetadata');
72
73
        $collector->collect(new Request(), new Response());
74
75
        $entities = $collector->getEntities();
0 ignored issues
show
Unused Code introduced by
$entities is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
76
        $this->assertEmpty($collector->getEntities());
77
    }
78
79
    public function testGetGroupedQueries()
80
    {
81
        $logger            = $this->getMockBuilder('Doctrine\DBAL\Logging\DebugStack')->getMock();
82
        $logger->queries   = [];
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
83
        $logger->queries[] = [
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
84
            'sql' => 'SELECT * FROM foo WHERE bar = :bar',
85
            'params' => [':bar' => 1],
86
            'types' => null,
87
            'executionMS' => 32,
88
        ];
89
        $logger->queries[] = [
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
90
            'sql' => 'SELECT * FROM foo WHERE bar = :bar',
91
            'params' => [':bar' => 2],
92
            'types' => null,
93
            'executionMS' => 25,
94
        ];
95
        $collector         = $this->createCollector([]);
96
        $collector->addLogger('default', $logger);
0 ignored issues
show
Documentation introduced by
$logger is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\DBAL\Logging\DebugStack>.

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...
97
        $collector->collect(new Request(), new Response());
98
        $groupedQueries = $collector->getGroupedQueries();
99
        $this->assertCount(1, $groupedQueries['default']);
100
        $this->assertSame('SELECT * FROM foo WHERE bar = :bar', $groupedQueries['default'][0]['sql']);
101
        $this->assertSame(2, $groupedQueries['default'][0]['count']);
102
103
        $logger->queries[] = [
0 ignored issues
show
Bug introduced by
Accessing queries on the interface PHPUnit\Framework\MockObject\MockObject suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
104
            'sql' => 'SELECT * FROM bar',
105
            'params' => [],
106
            'types' => null,
107
            'executionMS' => 25,
108
        ];
109
        $collector->collect(new Request(), new Response());
110
        $groupedQueries = $collector->getGroupedQueries();
111
        $this->assertCount(2, $groupedQueries['default']);
112
        $this->assertSame('SELECT * FROM bar', $groupedQueries['default'][1]['sql']);
113
        $this->assertSame(1, $groupedQueries['default'][1]['count']);
114
    }
115
116
    /**
117
     * @param string $entityFQCN
118
     *
119
     * @return ClassMetadataInfo
120
     */
121
    private function createEntityMetadata($entityFQCN)
122
    {
123
        $metadata            = new ClassMetadataInfo($entityFQCN);
124
        $metadata->name      = $entityFQCN;
125
        $metadata->reflClass = new ReflectionClass('stdClass');
126
127
        return $metadata;
128
    }
129
130
    /**
131
     * @param array $managers
132
     *
133
     * @return DoctrineDataCollector
134
     */
135
    private function createCollector(array $managers, bool $shouldValidateSchema = true)
136
    {
137
        $registry = $this->getMockBuilder('Doctrine\Persistence\ManagerRegistry')->getMock();
138
        $registry
139
            ->expects($this->any())
140
            ->method('getConnectionNames')
141
            ->will($this->returnValue(['default' => 'doctrine.dbal.default_connection']));
142
        $registry
143
            ->expects($this->any())
144
            ->method('getManagerNames')
145
            ->will($this->returnValue(['default' => 'doctrine.orm.default_entity_manager']));
146
        $registry
147
            ->expects($this->any())
148
            ->method('getManagers')
149
            ->will($this->returnValue($managers));
150
151
        return new DoctrineDataCollector($registry, $shouldValidateSchema);
0 ignored issues
show
Documentation introduced by
$registry is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\Persistence\ManagerRegistry>.

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...
152
    }
153
}
154