Passed
Push — oracle_tests ( 0a4664...8d5500 )
by David
02:39
created

testRawSqlOrderCountriesByUserCount()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 12
nc 4
nop 0
dl 0
loc 25
rs 8.8571
c 1
b 0
f 1
1
<?php
2
3
/*
4
 Copyright (C) 2006-2014 David Négrier - THE CODING MACHINE
5
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
*/
20
21
namespace TheCodingMachine\TDBM;
22
23
use Doctrine\DBAL\Platforms\MySqlPlatform;
24
use TheCodingMachine\TDBM\Utils\DefaultNamingStrategy;
25
use Psr\Log\LogLevel;
26
use Wa72\SimpleLogger\ArrayLogger;
27
28
class TDBMServiceTest extends TDBMAbstractServiceTest
29
{
30
    public function testGetLinkBetweenInheritedTables()
31
    {
32
        $this->assertEquals(['users', 'contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['contact', 'users']));
33
        $this->assertEquals(['users', 'contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['users', 'contact']));
34
        $this->assertEquals(['contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['person', 'contact']));
35
        $this->assertEquals(['users', 'contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['users']));
36
        $this->assertEquals(['person'], $this->tdbmService->_getLinkBetweenInheritedTables(['person']));
37
    }
38
39
    public function testGetRelatedTablesByInheritance()
40
    {
41
        $contactRelatedTables = $this->tdbmService->_getRelatedTablesByInheritance('contact');
42
        $this->assertCount(3, $contactRelatedTables);
43
        $this->assertContains('users', $contactRelatedTables);
44
        $this->assertContains('contact', $contactRelatedTables);
45
        $this->assertContains('person', $contactRelatedTables);
46
        $this->assertEquals(['person', 'contact', 'users'], $this->tdbmService->_getRelatedTablesByInheritance('users'));
47
        $this->assertEquals(['person', 'contact', 'users'], $this->tdbmService->_getRelatedTablesByInheritance('person'));
48
    }
49
50
    /**
51
     * @expectedException \TheCodingMachine\TDBM\TDBMException
52
     *
53
     * @throws TDBMException
54
     */
55
    public function testGetPrimaryKeysFromIndexedPrimaryKeysException()
56
    {
57
        $this->tdbmService->_getPrimaryKeysFromIndexedPrimaryKeys('users', [5, 4]);
58
    }
59
60
    /**
61
     * @expectedException \TheCodingMachine\TDBM\TDBMException
62
     *
63
     * @throws TDBMException
64
     */
65
    public function testGetLinkBetweenInheritedTablesExceptions()
66
    {
67
        $this->tdbmService->_getLinkBetweenInheritedTables(['contact', 'country']);
68
    }
69
70
    public function testHashPrimaryKey()
71
    {
72
        $reflection = new \ReflectionClass(get_class($this->tdbmService));
73
        $method = $reflection->getMethod('getObjectHash');
74
        $method->setAccessible(true);
75
76
        $result = $method->invokeArgs($this->tdbmService, [
77
            ['id' => 42],
78
        ]);
79
        $this->assertEquals(42, $result);
80
81
        // Check that multiple primary keys are insensitive to column order
82
        $result1 = $method->invokeArgs($this->tdbmService, [
83
            ['id1' => 42, 'id2' => 24],
84
        ]);
85
        $result2 = $method->invokeArgs($this->tdbmService, [
86
            ['id2' => 24, 'id1' => 42],
87
        ]);
88
        $this->assertEquals($result1, $result2);
89
    }
90
91
    public function testInsertAndUpdateAndDelete()
92
    {
93
        $object = new TDBMObject('users');
94
        $object->setProperty('login', 'john.doe');
95
        $object->setProperty('country_id', 3);
96
        $object->setProperty('name', 'John Doe', 'person');
97
        $object->setProperty('email', '[email protected]', 'contact');
98
99
        $this->tdbmService->save($object);
100
101
        $this->assertNotEmpty($object->getProperty('id', 'person'));
102
        $this->assertNotEmpty($object->getProperty('id', 'users'));
103
        $this->assertEquals($object->getProperty('id', 'person'), $object->getProperty('id', 'users'));
104
105
        $object->setProperty('country_id', 2, 'users');
106
107
        $this->tdbmService->save($object);
108
109
        $this->tdbmService->delete($object);
110
    }
111
112
    public function testInsertMultipleDataAtOnceInInheritance()
113
    {
114
        $object = new TDBMObject();
115
        $object->setProperty('login', 'jane.doe', 'users');
116
        $object->setProperty('name', 'Jane Doe', 'person');
117
        $object->setProperty('country_id', 1, 'users');
118
        $object->setProperty('email', '[email protected]', 'contact');
119
120
        $this->tdbmService->save($object);
121
122
        $this->assertNotEmpty($object->getProperty('id', 'person'));
123
        $this->assertNotEmpty($object->getProperty('id', 'users'));
124
        $this->assertEquals($object->getProperty('id', 'person'), $object->getProperty('id', 'users'));
125
    }
126
127
    public function testCompleteSave()
128
    {
129
        $beans = $this->tdbmService->findObjects('users', 'users.login = :login', ['login' => 'jane.doe'], null, [], null, TDBMObject::class);
130
        $jane = $beans[0];
131
        $jane->setProperty('country_id', 2, 'users');
132
133
        $this->tdbmService->completeSave();
134
    }
135
136
    public function testCompleteSave2()
137
    {
138
        $beans = $this->tdbmService->findObjects('users', 'users.login = :login', ['login' => 'jane.doe'], null, [], null, TDBMObject::class);
139
        $jane = $beans[0];
140
141
        $this->assertEquals(2, $jane->getProperty('country_id', 'users'));
142
    }
143
144 View Code Duplication
    public function testUpdatePrimaryKey()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
145
    {
146
        $object = new TDBMObject('rights');
147
        $object->setProperty('label', 'CAN_EDIT_BOUK');
148
149
        $this->tdbmService->save($object);
150
151
        $object->setProperty('label', 'CAN_EDIT_BOOK');
152
153
        $this->tdbmService->save($object);
154
    }
155
156
    /**
157
     * @expectedException \TheCodingMachine\TDBM\TDBMInvalidOperationException
158
     *
159
     * @throws TDBMInvalidOperationException
160
     */
161
    public function testCannotDeleteDetachedObjects()
162
    {
163
        $object = new TDBMObject('rights');
164
        $object->setProperty('label', 'CAN_DELETE');
165
166
        $this->tdbmService->delete($object);
167
    }
168
169
    public function testDeleteNewObject()
170
    {
171
        $object = new TDBMObject('rights');
172
        $object->setProperty('label', 'CAN_DELETE');
173
174
        $this->tdbmService->attach($object);
175
176
        $this->tdbmService->delete($object);
177
178
        $exceptionRaised = false;
179
        try {
180
            $this->tdbmService->save($object);
181
        } catch (TDBMInvalidOperationException $e) {
182
            $exceptionRaised = true;
183
        }
184
        $this->assertTrue($exceptionRaised);
185
    }
186
187 View Code Duplication
    public function testDeleteLoadedObject()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
188
    {
189
        $object = new TDBMObject('rights');
190
        $object->setProperty('label', 'CAN_DELETE');
191
192
        $this->tdbmService->save($object);
193
194
        $object->setProperty('label', 'CAN_DELETE2');
195
196
        $this->tdbmService->delete($object);
197
198
        // Try to delete a deleted object (this should do nothing)
199
        $this->tdbmService->delete($object);
200
    }
201
202
    public function testFindObjects()
203
    {
204
        /*$magicQuery = new MagicQuery($this->tdbmService->getConnection());
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
205
        $result = $magicQuery->parse("SELECT DISTINCT users.id, users.login FROM users");
206
        var_dump($result);*/
207
208
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
209
        $beans2 = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], null, TDBMObject::class);
210
211
        foreach ($beans as $bean) {
212
            $bean1 = $bean;
213
            break;
214
        }
215
216
        foreach ($beans2 as $bean) {
217
            $bean2 = $bean;
218
            break;
219
        }
220
221
        $this->assertTrue($bean1 === $bean2);
0 ignored issues
show
Bug introduced by
The variable $bean1 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $bean2 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
222
        $this->assertEquals(5, $beans->count());
223
        $this->assertEquals(1, $beans2->count());
224
225
        //$this->assertTrue($beans[0] === $beans2[0]);
0 ignored issues
show
Unused Code Comprehensibility introduced by
77% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
226
        //var_dump($beans);
227
    }
228
229
    public function testRawSqlFilterCountriesByUserCount()
230
    {
231
        $this->onlyMySql();
232
233
        $sql = <<<SQL
234
SELECT country.*, GROUP_CONCAT(users.id) AS ids
235
FROM country
236
JOIN users ON country.id= users.country_id
237
GROUP BY country.id
238
HAVING COUNT(users.id) > 1;
239
SQL;
240
        /** @var Test\Dao\Bean\CountryBean[]|\Porpaginas\Result $beans */
241
        $beans = $this->tdbmService->findObjectsFromRawSql('country', $sql, [], null, Test\Dao\Bean\CountryBean::class);
242
243
        $count = 0;
244
        foreach ($beans as $country) {
245
            $this->assertGreaterThan(1, count($country->getUsers()));
246
            $count++;
247
        }
248
        $this->assertEquals($count, $beans->count());
249
    }
250
251
    public function testRawSqlOrderCountriesByUserCount()
252
    {
253
        $this->onlyMySql();
254
255
        $sql = <<<SQL
256
SELECT country.*, GROUP_CONCAT(users.id) AS ids
257
FROM country
258
JOIN users ON country.id= users.country_id
259
GROUP BY country.id
260
ORDER BY COUNT(users.id);
261
SQL;
262
263
        /** @var Test\Dao\Bean\CountryBean[]|\Porpaginas\Result $beans */
264
        $beans = $this->tdbmService->findObjectsFromRawSql('country', $sql, [], null, Test\Dao\Bean\CountryBean::class);
265
266
        $count = 0;
267
        foreach ($beans as $country) {
268
            $count++;
269
        }
270
        $this->assertEquals($count, $beans->count());
271
272
        for ($i = 1; $i < count($beans); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
273
            $this->assertLessThanOrEqual(count($beans[$i]->getUsers()), count($beans[$i - 1]->getUsers()));
274
        }
275
    }
276
277
    public function testRawSqlOrderUsersByCustomRoleOrder()
278
    {
279
        $this->onlyMySql();
280
281
        $sql = <<<SQL
282
SELECT `person`.*, `contact`.*, `users`.*
283
FROM `contact`
284
JOIN `users` ON `users`.`id` = `contact`.`id`
285
JOIN `person` ON `person`.`id` = `users`.`id`
286
JOIN `users_roles` ON users.id = users_roles.user_id
287
JOIN `roles` ON roles.id = users_roles.role_id
288
GROUP BY users.id
289
ORDER BY MAX(IF(roles.name = 'Admins', 3, IF(roles.name = 'Writers', 2, IF(roles.name = 'Singers', 1, 0)))) DESC
290
SQL;
291
292
        /** @var Test\Dao\Bean\UserBean[]|\Porpaginas\Result $beans */
293
        $beans = $this->tdbmService->findObjectsFromRawSql('contact', $sql, [], null, Test\Dao\Bean\UserBean::class);
294
295
        function getCustomOrder(Test\Dao\Bean\UserBean $contact)
296
        {
297
            $max = 0;
298
            foreach ($contact->getRoles() as $role) {
299
                $max = max($max, [
300
                    'Admins' => 3,
301
                    'Writers' => 2,
302
                    'Singers' => 1,
303
                ][$role->getName()]);
304
            }
305
            return $max;
306
        }
307
308
        $this->assertCount(4, $beans);
309
310
        for ($i = 1; $i < count($beans); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
311
            $this->assertGreaterThanOrEqual(getCustomOrder($beans[$i]), getCustomOrder($beans[$i - 1]), 'Beans order does not comply with expected result.');
312
        }
313
    }
314
315
    public function testArrayAccess()
316
    {
317
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
318
319
        $this->assertTrue(isset($beans[0]));
320
        $this->assertFalse(isset($beans[42]));
321
        $this->assertEquals(1, $beans[0]->getProperty('id', 'person'));
322
323
        $result1 = [];
324
        foreach ($beans as $bean) {
325
            $result1[] = $bean;
326
        }
327
328
        $result2 = [];
329
        foreach ($beans as $bean) {
330
            $result2[] = $bean;
331
        }
332
333
        $this->assertEquals($result1, $result2);
334
        $this->assertTrue($result1[0] === $result2[0]);
335
    }
336
337
    /**
338
     * @expectedException \TheCodingMachine\TDBM\TDBMInvalidOffsetException
339
     *
340
     * @throws TDBMInvalidOffsetException
341
     */
342
    public function testArrayAccessException()
343
    {
344
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
345
346
        $beans[-1];
347
    }
348
349
    /**
350
     * @expectedException \TheCodingMachine\TDBM\TDBMInvalidOffsetException
351
     *
352
     * @throws TDBMInvalidOffsetException
353
     */
354
    public function testArrayAccessException2()
355
    {
356
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
357
358
        $beans['foo'];
359
    }
360
361
    /**
362
     * @expectedException \TheCodingMachine\TDBM\TDBMException
363
     *
364
     * @throws TDBMException
365
     */
366 View Code Duplication
    public function testBeanGetException()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
367
    {
368
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
369
        $bean = $beans[0];
370
371
        // we don't specify the table on inheritance table => exception.
372
        $bean->getProperty('id');
373
    }
374
375
    /**
376
     * @expectedException \TheCodingMachine\TDBM\TDBMException
377
     *
378
     * @throws TDBMException
379
     */
380 View Code Duplication
    public function testBeanSetException()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
381
    {
382
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
383
        $bean = $beans[0];
384
385
        // we don't specify the table on inheritance table => exception.
386
        $bean->setProperty('name', 'foo');
387
    }
388
389
    public function testTake()
390
    {
391
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
392
393
        $page = $beans->take(0, 2);
394
395
        $this->assertEquals(2, $page->count());
396
397
        $results = [];
398
        foreach ($page as $result) {
399
            $results[] = $result;
400
        }
401
        $this->assertCount(2, $results);
402
403
        $this->assertEquals(5, $page->totalCount());
404
405
        $page = $beans->take(1, 1);
406
407
        $this->assertEquals(1, $page->count());
408
409
        $resultArray = $page->toArray();
410
        $this->assertCount(1, $resultArray);
411
        $this->assertTrue($resultArray[0] === $page[0]);
412
        // Test page isset
413
        $this->assertTrue(isset($page[0]));
414
    }
415
416
    public function testTakeInCursorMode()
417
    {
418
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], TDBMService::MODE_CURSOR, TDBMObject::class);
419
420
        $page = $beans->take(0, 2);
421
422
        $this->assertEquals(2, $page->count());
423
        $this->assertEquals(0, $page->getCurrentOffset());
424
        $this->assertEquals(2, $page->getCurrentLimit());
425
        $this->assertEquals(1, $page->getCurrentPage());
426
427
        $results = [];
428
        foreach ($page as $result) {
429
            $results[] = $result;
430
        }
431
        $this->assertCount(2, $results);
432
433
        $this->assertEquals(5, $page->totalCount());
434
435
        $page = $beans->take(1, 1);
436
        $this->assertEquals(1, $page->getCurrentOffset());
437
        $this->assertEquals(1, $page->getCurrentLimit());
438
        $this->assertEquals(2, $page->getCurrentPage());
439
440
        $this->assertEquals(1, $page->count());
441
    }
442
443
    public function testMap()
444
    {
445
        $beans = $this->tdbmService->findObjects('person', null, [], 'person.id ASC', [], null, TDBMObject::class);
446
447
        $results = $beans->map(function ($item) {
448
            return $item->getProperty('id', 'person');
449
        })->toArray();
450
451
        $this->assertEquals([1, 2, 3, 4, 6], $results);
452
453
        // Same test with page
454
        $page = $beans->take(0, 2);
455
456
        $results = $page->map(function ($item) {
457
            return $item->getProperty('id', 'person');
458
        })->toArray();
459
460
        $this->assertEquals([1, 2], $results);
461
    }
462
463
    /**
464
     * @expectedException \TheCodingMachine\TDBM\TDBMException
465
     *
466
     * @throws TDBMException
467
     */
468
    public function testUnsetException()
469
    {
470
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
471
472
        unset($beans[0]);
473
    }
474
475
    /**
476
     * @expectedException \TheCodingMachine\TDBM\TDBMException
477
     *
478
     * @throws TDBMException
479
     */
480
    public function testSetException()
481
    {
482
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
483
484
        $beans[0] = 'foo';
485
    }
486
487
    /**
488
     * @expectedException \TheCodingMachine\TDBM\TDBMException
489
     *
490
     * @throws TDBMException
491
     */
492
    public function testPageUnsetException()
493
    {
494
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
495
        $page = $beans->take(0, 1);
496
        unset($page[0]);
497
    }
498
499
    /**
500
     * @expectedException \TheCodingMachine\TDBM\TDBMException
501
     *
502
     * @throws TDBMException
503
     */
504
    public function testPageSetException()
505
    {
506
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
507
        $page = $beans->take(0, 1);
508
        $page[0] = 'foo';
509
    }
510
511 View Code Duplication
    public function testToArray()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
512
    {
513
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], null, TDBMObject::class);
514
515
        $beanArray = $beans->toArray();
516
517
        $this->assertCount(1, $beanArray);
518
        $this->assertEquals(1, $beanArray[0]->getProperty('id', 'contact'));
519
    }
520
521
    public function testCursorMode()
522
    {
523
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], TDBMService::MODE_CURSOR, TDBMObject::class);
524
525
        $this->assertInstanceOf('\\TheCodingMachine\\TDBM\\ResultIterator', $beans);
526
527
        $result = [];
528
        foreach ($beans as $bean) {
529
            $result[] = $bean;
530
        }
531
532
        $this->assertCount(1, $result);
533
534
        // In cursor mode, access by array causes an exception.
535
        $exceptionTriggered = false;
536
        try {
537
            $beans[0];
538
        } catch (TDBMInvalidOperationException $e) {
539
            $exceptionTriggered = true;
540
        }
541
        $this->assertTrue($exceptionTriggered);
542
543
        $exceptionTriggered = false;
544
        try {
545
            isset($beans[0]);
546
        } catch (TDBMInvalidOperationException $e) {
0 ignored issues
show
Unused Code introduced by
catch (\TheCodingMachine...tionTriggered = true; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
547
            $exceptionTriggered = true;
548
        }
549
        $this->assertTrue($exceptionTriggered);
550
    }
551
552
    public function testSetFetchMode()
553
    {
554
        $this->tdbmService->setFetchMode(TDBMService::MODE_CURSOR);
555
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], null, TDBMObject::class);
556
557
        $this->assertInstanceOf('\\TheCodingMachine\\TDBM\\ResultIterator', $beans);
558
559
        // In cursor mode, access by array causes an exception.
560
        $exceptionTriggered = false;
561
        try {
562
            $beans[0];
563
        } catch (TDBMInvalidOperationException $e) {
564
            $exceptionTriggered = true;
565
        }
566
        $this->assertTrue($exceptionTriggered);
567
    }
568
569
    /**
570
     * @expectedException \TheCodingMachine\TDBM\TDBMException
571
     *
572
     * @throws TDBMException
573
     */
574
    public function testInvalidSetFetchMode()
575
    {
576
        $this->tdbmService->setFetchMode('foo');
577
    }
578
579
    /**
580
     * @expectedException \TheCodingMachine\TDBM\TDBMException
581
     *
582
     * @throws TDBMException
583
     */
584
    public function testCursorModeException()
585
    {
586
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], 'foobaz');
0 ignored issues
show
Unused Code introduced by
$beans 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...
587
    }
588
589
    /**
590
     * @expectedException \TheCodingMachine\TDBM\TDBMException
591
     *
592
     * @throws TDBMException
593
     */
594
    public function testTableNameException()
595
    {
596
        $beans = $this->tdbmService->findObjects('foo bar');
0 ignored issues
show
Unused Code introduced by
$beans 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...
597
    }
598
599
    public function testLinkedTableFetch()
600
    {
601
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, ['country'], null, TDBMObject::class);
0 ignored issues
show
Unused Code introduced by
$beans 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...
602
    }
603
604
    public function testFindObject()
605
    {
606
        $bean = $this->tdbmService->findObject('contact', 'contact.id = :id', ['id' => -42], [], TDBMObject::class);
607
        $this->assertNull($bean);
608
    }
609
610
    /**
611
     * @expectedException \TheCodingMachine\TDBM\NoBeanFoundException
612
     *
613
     * @throws NoBeanFoundException
614
     */
615
    public function testFindObjectOrFail()
616
    {
617
        $bean = $this->tdbmService->findObjectOrFail('contact', 'contact.id = :id', ['id' => -42], [], TDBMObject::class);
0 ignored issues
show
Unused Code introduced by
$bean 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...
618
    }
619
620
    /**
621
     * @expectedException \TheCodingMachine\TDBM\DuplicateRowException
622
     *
623
     * @throws DuplicateRowException
624
     */
625
    public function testFindObjectDuplicateRow()
626
    {
627
        $bean = $this->tdbmService->findObject('contact');
0 ignored issues
show
Unused Code introduced by
$bean 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...
628
    }
629
630 View Code Duplication
    public function testFindObjectsByBean()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
631
    {
632
        $countryBean = $this->tdbmService->findObject('country', 'id = :id', ['id' => 1], [], TDBMObject::class);
633
634
        $users = $this->tdbmService->findObjects('users', $countryBean, [], null, [], null, TDBMObject::class);
0 ignored issues
show
Bug introduced by
It seems like $countryBean defined by $this->tdbmService->find...TDBM\TDBMObject::class) on line 632 can also be of type object<TheCodingMachine\TDBM\AbstractTDBMObject>; however, TheCodingMachine\TDBM\TDBMService::findObjects() does only seem to accept string|array|null, 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...
635
        $this->assertCount(1, $users);
636
        $this->assertEquals('jean.dupont', $users[0]->getProperty('login', 'users'));
637
    }
638
639
    /**
640
     * @expectedException \TheCodingMachine\TDBM\TDBMException
641
     *
642
     * @throws TDBMException
643
     * @throws TDBMInvalidOperationException
644
     */
645
    public function testBeanWithoutStatus()
646
    {
647
        $object = new TDBMObject('users');
648
        $object->setProperty('login', 'john.doe');
649
        $object->setProperty('country_id', 3);
650
        $object->setProperty('name', 'John Doe', 'person');
651
        $object->setProperty('email', '[email protected]', 'contact');
652
        $object->_setStatus(null);
653
        $this->tdbmService->save($object);
654
    }
655
656
    public function testFindObjectsFromSql()
657
    {
658
        $roles = $this->tdbmService->findObjectsFromSql('roles', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
659
            'rights.label = :right', array('right' => 'CAN_SING'), 'roles.name DESC');
660
        $this->assertCount(2, $roles);
661
        $this->assertInstanceOf(AbstractTDBMObject::class, $roles[0]);
662
    }
663
664
    /**
665
     * @expectedException \TheCodingMachine\TDBM\TDBMException
666
     *
667
     * @throws TDBMException
668
     */
669
    public function testFindObjectsFromSqlBadTableName()
670
    {
671
        $this->tdbmService->findObjectsFromSql('#{azerty', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
672
            'rights.label = :right', array('right' => 'CAN_SING'), 'name DESC');
673
    }
674
675
    /**
676
     * @expectedException \TheCodingMachine\TDBM\TDBMException
677
     *
678
     * @throws TDBMException
679
     */
680
    public function testFindObjectsFromSqlGroupBy()
681
    {
682
        $roles = $this->tdbmService->findObjectsFromSql('roles', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
683
            'rights.label = :right GROUP BY roles.name', array('right' => 'CAN_SING'), 'name DESC');
684
        $role = $roles[0];
0 ignored issues
show
Unused Code introduced by
$role 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...
685
    }
686
687
    public function testFindObjectFromSql()
688
    {
689
        $role = $this->tdbmService->findObjectFromSql('roles', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
690
            'rights.label = :right AND name = :name', array('right' => 'CAN_SING', 'name' => 'Singers'));
691
        $this->assertInstanceOf(AbstractTDBMObject::class, $role);
692
    }
693
694
    /**
695
     * @expectedException \TheCodingMachine\TDBM\DuplicateRowException
696
     *
697
     * @throws DuplicateRowException
698
     */
699
    public function testFindObjectFromSqlException()
700
    {
701
        $this->tdbmService->findObjectFromSql('roles', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
702
            'rights.label = :right', array('right' => 'CAN_SING'));
703
    }
704
705 View Code Duplication
    public function testFindObjectsFromSqlHierarchyDown()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
706
    {
707
        $users = $this->tdbmService->findObjectsFromSql('person', 'person', 'name LIKE :name OR name LIKE :name2',
708
            array('name' => 'Robert Marley', 'name2' => 'Bill Shakespeare'), null, null, TDBMObject::class);
709
        $this->assertCount(2, $users);
710
        $this->assertSame('robert.marley', $users[0]->getProperty('login', 'users'));
711
    }
712
713 View Code Duplication
    public function testFindObjectsFromSqlHierarchyUp()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
714
    {
715
        $users = $this->tdbmService->findObjectsFromSql('users', 'users', 'login LIKE :login OR login LIKE :login2',
716
            array('login' => 'robert.marley', 'login2' => 'bill.shakespeare'), null, null, TDBMObject::class);
717
        $this->assertCount(2, $users);
718
        $this->assertSame('Robert Marley', $users[0]->getProperty('name', 'person'));
719
    }
720
721
    public function testLogger()
722
    {
723
        $arrayLogger = new ArrayLogger();
724
        $tdbmService = new TDBMService(new Configuration('TheCodingMachine\\TDBM\\Test\\Dao\\Bean', 'TheCodingMachine\\TDBM\\Test\\Dao', self::getConnection(), $this->getNamingStrategy(), null, null, $arrayLogger));
725
726
        $tdbmService->setLogLevel(LogLevel::DEBUG);
727
        $beans = $tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
728
        $beans->first();
729
730
        $this->assertNotEmpty($arrayLogger->get());
731
    }
732
733
    public function testFindObjectsCountWithOneToManyLink()
734
    {
735
        $countries = $this->tdbmService->findObjects('country', "users.status = 'on' OR users.status = 'off'");
736
737
        $this->assertEquals(3, $countries->count());
738
    }
739
740
    public function testFindObjectsFromSqlCountWithOneToManyLink()
741
    {
742
        $countries = $this->tdbmService->findObjectsFromSql('country', 'country LEFT JOIN users ON country.id = users.country_id', "users.status = 'on' OR users.status = 'off'");
743
744
        $this->assertEquals(3, $countries->count());
745
    }
746
747
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
748
        public function testObjectAsFilter() {
749
            $dpt = $this->tdbmService->getObject('departements', 1);
750
            $dpt2 =  $this->tdbmService->getObject('departements', $dpt);
751
            $this->assertEquals($dpt, $dpt2);
752
        }
753
754
        public function testOneWayAndTheOpposite() {
755
            $this->tdbmService->getObjects('utilisateur_entite', new EqualFilter('entites', 'appellation', 'foo'));
756
            $this->tdbmService->getObjects('entites', new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'));
757
        }
758
759
        public function testOneWayAndTheOpposite2() {
760
            $this->tdbmService->getObjects('utilisateur_entite', new EqualFilter('departements', 'id', '1'));
761
            $this->tdbmService->getObjects('departements', new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'));
762
        }
763
764
        public function testOneWayAndTheOpposite3() {
765
            $this->tdbmService->getObjects('utilisateur_entite',
766
                    [
767
                    new EqualFilter('entites', 'appellation', 1),
768
                    ]
769
            );
770
            $this->tdbmService->getObjects('entites', [
771
                        new EqualFilter('departements', 'id', 1),
772
                        new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'),
773
                    ]
774
            );
775
        }
776
777
        public function testOneWayAndTheOpposite4() {
778
            $this->tdbmService->getObjects('utilisateur_entite', null,
779
                    [
780
                    new OrderByColumn('entites', 'appellation', 'ASC'),
781
                    ]
782
            );
783
            $this->tdbmService->getObjects('entites', new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'),
784
                    [
785
                    new OrderByColumn('departements', 'id', 'ASC')
786
                    ]
787
            );
788
        }
789
790
        public function testTDBMObjectArrayMultipleForeach() {
791
            $results = $this->tdbmService->getObjects('departements');
792
            $this->assertTrue(is_array($results));
793
            $count = 0;
794
            foreach ($results as $result) {
795
                $count++;
796
            }
797
            $this->assertEquals(95, $count);
798
799
            $count = 0;
800
            foreach ($results as $result) {
801
                $count++;
802
            }
803
            $this->assertEquals(95, $count);
804
805
        }
806
807
        public function testTDBMObjectsCursorMode() {
808
            $this->tdbmService->setFetchMode(TDBMService::MODE_CURSOR);
809
            $results = $this->tdbmService->getObjects('departements');
810
811
            $count = 0;
812
            foreach ($results as $result) {
813
                $count++;
814
            }
815
            $this->assertEquals(95, $count);
816
        }
817
818
        public function testTDBMObjectCursorMode() {
819
            $this->tdbmService->setFetchMode(TDBMService::MODE_CURSOR);
820
            $result = $this->tdbmService->getObject('departements', array(new EqualFilter('departements', 'id', 1)));
821
822
            $this->assertEquals("Ain", $result->nom);
823
        }
824
825
826
        public function testTDBMObjectArrayCount() {
827
            $results = $this->tdbmService->getObjects('departements');
828
            $this->assertEquals(95, count($results));
829
            $this->assertEquals(95, count($results));
830
831
        }
832
833
834
        public function testTDBMObjectArrayAccessByKey() {
835
            $results = $this->tdbmService->getObjects('departements');
836
837
            $this->assertEquals("Alpes Maritimes", $results[5]->nom);
838
        }
839
840
        public function testTDBMObjectArrayCountAfterForeach() {
841
            $results = $this->tdbmService->getObjects('departements');
842
            foreach ($results as $result) {
843
                // Do nothing
844
            }
845
            $this->assertEquals(95, count($results));
846
        }
847
848
        public function testStorage() {
849
            $results = $this->tdbmService->getObjects('departements');
850
851
            $result = $this->tdbmService->getObject('departements', 1);
852
853
            $this->assertTrue($results[0] === $result);
854
        }
855
856
        public function testCloneTDBMObject()
857
        {
858
            // Create a new object
859
            $object = $this->tdbmService->getNewObject('departements');
860
            $object->id_region = 22;
861
            $object->numero = '100';
862
            $object->nom = 'test';
863
            $object->nom_web = 'test';
864
            // Save the object
865
            $object->save();
866
867
            // Try to clone the object
868
            $cloneObject = clone $object;
869
            // Save the cloned object
870
            $cloneObject->save();
871
872
            $this->assertNotEquals($object->id, $cloneObject->id);
873
            $this->assertEquals($object->nom, $cloneObject->nom);
874
875
            $this->tdbmService->deleteObject($object);
876
            $this->tdbmService->deleteObject($cloneObject);
877
        }
878
    */
879
}
880