Test Failed
Pull Request — master (#12)
by Dorian
04:05
created

TDBMServiceTest::testPageSetException()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
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 TheCodingMachine\TDBM\Utils\DefaultNamingStrategy;
24
use Psr\Log\LogLevel;
25
use Wa72\SimpleLogger\ArrayLogger;
26
27
class TDBMServiceTest extends TDBMAbstractServiceTest
28
{
29
    public function testGetLinkBetweenInheritedTables()
30
    {
31
        $this->assertEquals(['users', 'contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['contact', 'users']));
32
        $this->assertEquals(['users', 'contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['users', 'contact']));
33
        $this->assertEquals(['contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['person', 'contact']));
34
        $this->assertEquals(['users', 'contact', 'person'], $this->tdbmService->_getLinkBetweenInheritedTables(['users']));
35
        $this->assertEquals(['person'], $this->tdbmService->_getLinkBetweenInheritedTables(['person']));
36
    }
37
38
    public function testGetRelatedTablesByInheritance()
39
    {
40
        $contactRelatedTables = $this->tdbmService->_getRelatedTablesByInheritance('contact');
41
        $this->assertCount(3, $contactRelatedTables);
42
        $this->assertContains('users', $contactRelatedTables);
43
        $this->assertContains('contact', $contactRelatedTables);
44
        $this->assertContains('person', $contactRelatedTables);
45
        $this->assertEquals(['person', 'contact', 'users'], $this->tdbmService->_getRelatedTablesByInheritance('users'));
46
        $this->assertEquals(['person', 'contact', 'users'], $this->tdbmService->_getRelatedTablesByInheritance('person'));
47
    }
48
49
    /**
50
     * @expectedException \TheCodingMachine\TDBM\TDBMException
51
     *
52
     * @throws TDBMException
53
     */
54
    public function testGetPrimaryKeysFromIndexedPrimaryKeysException()
55
    {
56
        $this->tdbmService->_getPrimaryKeysFromIndexedPrimaryKeys('users', [5, 4]);
57
    }
58
59
    /**
60
     * @expectedException \TheCodingMachine\TDBM\TDBMException
61
     *
62
     * @throws TDBMException
63
     */
64
    public function testGetLinkBetweenInheritedTablesExceptions()
65
    {
66
        $this->tdbmService->_getLinkBetweenInheritedTables(['contact', 'country']);
67
    }
68
69
    public function testHashPrimaryKey()
70
    {
71
        $reflection = new \ReflectionClass(get_class($this->tdbmService));
72
        $method = $reflection->getMethod('getObjectHash');
73
        $method->setAccessible(true);
74
75
        $result = $method->invokeArgs($this->tdbmService, [
76
            ['id' => 42],
77
        ]);
78
        $this->assertEquals(42, $result);
79
80
        // Check that multiple primary keys are insensitive to column order
81
        $result1 = $method->invokeArgs($this->tdbmService, [
82
            ['id1' => 42, 'id2' => 24],
83
        ]);
84
        $result2 = $method->invokeArgs($this->tdbmService, [
85
            ['id2' => 24, 'id1' => 42],
86
        ]);
87
        $this->assertEquals($result1, $result2);
88
    }
89
90
    public function testInsertAndUpdateAndDelete()
91
    {
92
        $object = new TDBMObject('users');
93
        $object->setProperty('login', 'john.doe');
94
        $object->setProperty('country_id', 3);
95
        $object->setProperty('name', 'John Doe', 'person');
96
        $object->setProperty('email', '[email protected]', 'contact');
97
98
        $this->tdbmService->save($object);
99
100
        $this->assertNotEmpty($object->getProperty('id', 'person'));
101
        $this->assertNotEmpty($object->getProperty('id', 'users'));
102
        $this->assertEquals($object->getProperty('id', 'person'), $object->getProperty('id', 'users'));
103
104
        $object->setProperty('country_id', 2, 'users');
105
106
        $this->tdbmService->save($object);
107
108
        $this->tdbmService->delete($object);
109
    }
110
111
    public function testInsertMultipleDataAtOnceInInheritance()
112
    {
113
        $object = new TDBMObject();
114
        $object->setProperty('login', 'jane.doe', 'users');
115
        $object->setProperty('name', 'Jane Doe', 'person');
116
        $object->setProperty('country_id', 1, 'users');
117
        $object->setProperty('email', '[email protected]', 'contact');
118
119
        $this->tdbmService->save($object);
120
121
        $this->assertNotEmpty($object->getProperty('id', 'person'));
122
        $this->assertNotEmpty($object->getProperty('id', 'users'));
123
        $this->assertEquals($object->getProperty('id', 'person'), $object->getProperty('id', 'users'));
124
    }
125
126
    public function testCompleteSave()
127
    {
128
        $beans = $this->tdbmService->findObjects('users', 'users.login = :login', ['login' => 'jane.doe'], null, [], null, TDBMObject::class);
129
        $jane = $beans[0];
130
        $jane->setProperty('country_id', 2, 'users');
131
132
        $this->tdbmService->completeSave();
133
    }
134
135
    public function testCompleteSave2()
136
    {
137
        $beans = $this->tdbmService->findObjects('users', 'users.login = :login', ['login' => 'jane.doe'], null, [], null, TDBMObject::class);
138
        $jane = $beans[0];
139
140
        $this->assertEquals(2, $jane->getProperty('country_id', 'users'));
141
    }
142
143 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...
144
    {
145
        $object = new TDBMObject('rights');
146
        $object->setProperty('label', 'CAN_EDIT_BOUK');
147
148
        $this->tdbmService->save($object);
149
150
        $object->setProperty('label', 'CAN_EDIT_BOOK');
151
152
        $this->tdbmService->save($object);
153
    }
154
155
    /**
156
     * @expectedException \TheCodingMachine\TDBM\TDBMInvalidOperationException
157
     *
158
     * @throws TDBMInvalidOperationException
159
     */
160
    public function testCannotDeleteDetachedObjects()
161
    {
162
        $object = new TDBMObject('rights');
163
        $object->setProperty('label', 'CAN_DELETE');
164
165
        $this->tdbmService->delete($object);
166
    }
167
168
    public function testDeleteNewObject()
169
    {
170
        $object = new TDBMObject('rights');
171
        $object->setProperty('label', 'CAN_DELETE');
172
173
        $this->tdbmService->attach($object);
174
175
        $this->tdbmService->delete($object);
176
177
        $exceptionRaised = false;
178
        try {
179
            $this->tdbmService->save($object);
180
        } catch (TDBMInvalidOperationException $e) {
181
            $exceptionRaised = true;
182
        }
183
        $this->assertTrue($exceptionRaised);
184
    }
185
186 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...
187
    {
188
        $object = new TDBMObject('rights');
189
        $object->setProperty('label', 'CAN_DELETE');
190
191
        $this->tdbmService->save($object);
192
193
        $object->setProperty('label', 'CAN_DELETE2');
194
195
        $this->tdbmService->delete($object);
196
197
        // Try to delete a deleted object (this should do nothing)
198
        $this->tdbmService->delete($object);
199
    }
200
201
    public function testFindObjects()
202
    {
203
        /*$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...
204
        $result = $magicQuery->parse("SELECT DISTINCT users.id, users.login FROM users");
205
        var_dump($result);*/
206
207
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
208
        $beans2 = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], null, TDBMObject::class);
209
210
        foreach ($beans as $bean) {
211
            $bean1 = $bean;
212
            break;
213
        }
214
215
        foreach ($beans2 as $bean) {
216
            $bean2 = $bean;
217
            break;
218
        }
219
220
        $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...
221
        $this->assertEquals(5, $beans->count());
222
        $this->assertEquals(1, $beans2->count());
223
224
        //$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...
225
        //var_dump($beans);
226
    }
227
228
    public function testRawSqlFilterCountriesByUserCount()
229
    {
230
        $sql = <<<SQL
231
SELECT country.*, GROUP_CONCAT(users.id) AS ids
232
FROM country
233
JOIN users ON country.id= users.country_id
234
GROUP BY country.id
235
HAVING COUNT(users.id) > 1;
236
SQL;
237
        /** @var Test\Dao\Bean\CountryBean[]|\Porpaginas\Result $beans */
238
        $beans = $this->tdbmService->findObjectsFromRawSql('country', $sql, [], null, Test\Dao\Bean\CountryBean::class);
239
240
        $count = 0;
241
        foreach ($beans as $country) {
242
            $this->assertGreaterThan(1, count($country->getUsers()));
243
            $count++;
244
        }
245
        $this->assertEquals($count, $beans->count());
246
    }
247
248
    public function testRawSqlOrderCountriesByUserCount()
249
    {
250
        $sql = <<<SQL
251
SELECT country.*, GROUP_CONCAT(users.id) AS ids
252
FROM country
253
JOIN users ON country.id= users.country_id
254
GROUP BY country.id
255
ORDER BY COUNT(users.id);
256
SQL;
257
258
        /** @var Test\Dao\Bean\CountryBean[]|\Porpaginas\Result $beans */
259
        $beans = $this->tdbmService->findObjectsFromRawSql('country', $sql, [], null, Test\Dao\Bean\CountryBean::class);
260
261
        $count = 0;
262
        foreach ($beans as $country) {
263
            $count++;
264
        }
265
        $this->assertEquals($count, $beans->count());
266
267
        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...
268
            $this->assertLessThanOrEqual(count($beans[$i]->getUsers()), count($beans[$i - 1]->getUsers()));
269
        }
270
    }
271
272
    public function testRawSqlOrderUsersByCustomRoleOrder()
273
    {
274
        $sql = <<<SQL
275
SELECT `person`.*, `contact`.*, `users`.*
276
FROM `contact`
277
JOIN `users` ON `users`.`id` = `contact`.`id`
278
JOIN `person` ON `person`.`id` = `users`.`id`
279
JOIN `users_roles` ON users.id = users_roles.user_id
280
JOIN `roles` ON roles.id = users_roles.role_id
281
GROUP BY users.id
282
ORDER BY MAX(IF(roles.name = 'Admins', 3, IF(roles.name = 'Writers', 2, IF(roles.name = 'Singers', 1, 0)))) DESC
283
SQL;
284
285
        /** @var Test\Dao\Bean\UserBean[]|\Porpaginas\Result $beans */
286
        $beans = $this->tdbmService->findObjectsFromRawSql('contact', $sql, [], null, Test\Dao\Bean\UserBean::class);
287
288
        function getCustomOrder(Test\Dao\Bean\UserBean $contact) {
289
            $max = 0;
290
            foreach ($contact->getRoles() as $role) {
291
                $max = max($max, [
292
                    'Admins' => 3,
293
                    'Writers' => 2,
294
                    'Singers' => 1,
295
                ][$role->getName()]);
296
            }
297
            return $max;
298
        }
299
300
        $this->assertCount(4, $beans);
301
302
        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...
303
            $this->assertGreaterThanOrEqual(getCustomOrder($beans[$i]), getCustomOrder($beans[$i - 1]), 'Beans order does not comply with expected result.');
304
        }
305
    }
306
307
    public function testArrayAccess()
308
    {
309
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
310
311
        $this->assertTrue(isset($beans[0]));
312
        $this->assertFalse(isset($beans[42]));
313
        $this->assertEquals(1, $beans[0]->getProperty('id', 'person'));
314
315
        $result1 = [];
316
        foreach ($beans as $bean) {
317
            $result1[] = $bean;
318
        }
319
320
        $result2 = [];
321
        foreach ($beans as $bean) {
322
            $result2[] = $bean;
323
        }
324
325
        $this->assertEquals($result1, $result2);
326
        $this->assertTrue($result1[0] === $result2[0]);
327
    }
328
329
    /**
330
     * @expectedException \TheCodingMachine\TDBM\TDBMInvalidOffsetException
331
     *
332
     * @throws TDBMInvalidOffsetException
333
     */
334
    public function testArrayAccessException()
335
    {
336
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
337
338
        $beans[-1];
339
    }
340
341
    /**
342
     * @expectedException \TheCodingMachine\TDBM\TDBMInvalidOffsetException
343
     *
344
     * @throws TDBMInvalidOffsetException
345
     */
346
    public function testArrayAccessException2()
347
    {
348
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
349
350
        $beans['foo'];
351
    }
352
353
    /**
354
     * @expectedException \TheCodingMachine\TDBM\TDBMException
355
     *
356
     * @throws TDBMException
357
     */
358 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...
359
    {
360
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
361
        $bean = $beans[0];
362
363
        // we don't specify the table on inheritance table => exception.
364
        $bean->getProperty('id');
365
    }
366
367
    /**
368
     * @expectedException \TheCodingMachine\TDBM\TDBMException
369
     *
370
     * @throws TDBMException
371
     */
372 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...
373
    {
374
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
375
        $bean = $beans[0];
376
377
        // we don't specify the table on inheritance table => exception.
378
        $bean->setProperty('name', 'foo');
379
    }
380
381
    public function testTake()
382
    {
383
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
384
385
        $page = $beans->take(0, 2);
386
387
        $this->assertEquals(2, $page->count());
388
389
        $results = [];
390
        foreach ($page as $result) {
391
            $results[] = $result;
392
        }
393
        $this->assertCount(2, $results);
394
395
        $this->assertEquals(5, $page->totalCount());
396
397
        $page = $beans->take(1, 1);
398
399
        $this->assertEquals(1, $page->count());
400
401
        $resultArray = $page->toArray();
402
        $this->assertCount(1, $resultArray);
403
        $this->assertTrue($resultArray[0] === $page[0]);
404
        // Test page isset
405
        $this->assertTrue(isset($page[0]));
406
    }
407
408
    public function testTakeInCursorMode()
409
    {
410
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], TDBMService::MODE_CURSOR, TDBMObject::class);
411
412
        $page = $beans->take(0, 2);
413
414
        $this->assertEquals(2, $page->count());
415
        $this->assertEquals(0, $page->getCurrentOffset());
416
        $this->assertEquals(2, $page->getCurrentLimit());
417
        $this->assertEquals(1, $page->getCurrentPage());
418
419
        $results = [];
420
        foreach ($page as $result) {
421
            $results[] = $result;
422
        }
423
        $this->assertCount(2, $results);
424
425
        $this->assertEquals(5, $page->totalCount());
426
427
        $page = $beans->take(1, 1);
428
        $this->assertEquals(1, $page->getCurrentOffset());
429
        $this->assertEquals(1, $page->getCurrentLimit());
430
        $this->assertEquals(2, $page->getCurrentPage());
431
432
        $this->assertEquals(1, $page->count());
433
    }
434
435
    public function testMap()
436
    {
437
        $beans = $this->tdbmService->findObjects('person', null, [], 'person.id ASC', [], null, TDBMObject::class);
438
439
        $results = $beans->map(function ($item) {
440
            return $item->getProperty('id', 'person');
441
        })->toArray();
442
443
        $this->assertEquals([1, 2, 3, 4, 6], $results);
444
445
        // Same test with page
446
        $page = $beans->take(0, 2);
447
448
        $results = $page->map(function ($item) {
449
            return $item->getProperty('id', 'person');
450
        })->toArray();
451
452
        $this->assertEquals([1, 2], $results);
453
    }
454
455
    /**
456
     * @expectedException \TheCodingMachine\TDBM\TDBMException
457
     *
458
     * @throws TDBMException
459
     */
460
    public function testUnsetException()
461
    {
462
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
463
464
        unset($beans[0]);
465
    }
466
467
    /**
468
     * @expectedException \TheCodingMachine\TDBM\TDBMException
469
     *
470
     * @throws TDBMException
471
     */
472
    public function testSetException()
473
    {
474
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
475
476
        $beans[0] = 'foo';
477
    }
478
479
    /**
480
     * @expectedException \TheCodingMachine\TDBM\TDBMException
481
     *
482
     * @throws TDBMException
483
     */
484
    public function testPageUnsetException()
485
    {
486
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
487
        $page = $beans->take(0, 1);
488
        unset($page[0]);
489
    }
490
491
    /**
492
     * @expectedException \TheCodingMachine\TDBM\TDBMException
493
     *
494
     * @throws TDBMException
495
     */
496
    public function testPageSetException()
497
    {
498
        $beans = $this->tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
499
        $page = $beans->take(0, 1);
500
        $page[0] = 'foo';
501
    }
502
503 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...
504
    {
505
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], null, TDBMObject::class);
506
507
        $beanArray = $beans->toArray();
508
509
        $this->assertCount(1, $beanArray);
510
        $this->assertEquals(1, $beanArray[0]->getProperty('id', 'contact'));
511
    }
512
513
    public function testCursorMode()
514
    {
515
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], TDBMService::MODE_CURSOR, TDBMObject::class);
516
517
        $this->assertInstanceOf('\\TheCodingMachine\\TDBM\\ResultIterator', $beans);
518
519
        $result = [];
520
        foreach ($beans as $bean) {
521
            $result[] = $bean;
522
        }
523
524
        $this->assertCount(1, $result);
525
526
        // In cursor mode, access by array causes an exception.
527
        $exceptionTriggered = false;
528
        try {
529
            $beans[0];
530
        } catch (TDBMInvalidOperationException $e) {
531
            $exceptionTriggered = true;
532
        }
533
        $this->assertTrue($exceptionTriggered);
534
535
        $exceptionTriggered = false;
536
        try {
537
            isset($beans[0]);
538
        } 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...
539
            $exceptionTriggered = true;
540
        }
541
        $this->assertTrue($exceptionTriggered);
542
    }
543
544
    public function testSetFetchMode()
545
    {
546
        $this->tdbmService->setFetchMode(TDBMService::MODE_CURSOR);
547
        $beans = $this->tdbmService->findObjects('contact', 'contact.id = :id', ['id' => 1], null, [], null, TDBMObject::class);
548
549
        $this->assertInstanceOf('\\TheCodingMachine\\TDBM\\ResultIterator', $beans);
550
551
        // In cursor mode, access by array causes an exception.
552
        $exceptionTriggered = false;
553
        try {
554
            $beans[0];
555
        } catch (TDBMInvalidOperationException $e) {
556
            $exceptionTriggered = true;
557
        }
558
        $this->assertTrue($exceptionTriggered);
559
    }
560
561
    /**
562
     * @expectedException \TheCodingMachine\TDBM\TDBMException
563
     *
564
     * @throws TDBMException
565
     */
566
    public function testInvalidSetFetchMode()
567
    {
568
        $this->tdbmService->setFetchMode('foo');
569
    }
570
571
    /**
572
     * @expectedException \TheCodingMachine\TDBM\TDBMException
573
     *
574
     * @throws TDBMException
575
     */
576
    public function testCursorModeException()
577
    {
578
        $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...
579
    }
580
581
    /**
582
     * @expectedException \TheCodingMachine\TDBM\TDBMException
583
     *
584
     * @throws TDBMException
585
     */
586
    public function testTableNameException()
587
    {
588
        $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...
589
    }
590
591
    public function testLinkedTableFetch()
592
    {
593
        $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...
594
    }
595
596
    public function testFindObject()
597
    {
598
        $bean = $this->tdbmService->findObject('contact', 'contact.id = :id', ['id' => -42], [], TDBMObject::class);
599
        $this->assertNull($bean);
600
    }
601
602
    /**
603
     * @expectedException \TheCodingMachine\TDBM\NoBeanFoundException
604
     *
605
     * @throws NoBeanFoundException
606
     */
607
    public function testFindObjectOrFail()
608
    {
609
        $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...
610
    }
611
612
    /**
613
     * @expectedException \TheCodingMachine\TDBM\DuplicateRowException
614
     *
615
     * @throws DuplicateRowException
616
     */
617
    public function testFindObjectDuplicateRow()
618
    {
619
        $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...
620
    }
621
622 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...
623
    {
624
        $countryBean = $this->tdbmService->findObject('country', 'id = :id', ['id' => 1], [], TDBMObject::class);
625
626
        $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 624 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...
627
        $this->assertCount(1, $users);
628
        $this->assertEquals('jean.dupont', $users[0]->getProperty('login', 'users'));
629
    }
630
631
    /**
632
     * @expectedException \TheCodingMachine\TDBM\TDBMException
633
     *
634
     * @throws TDBMException
635
     * @throws TDBMInvalidOperationException
636
     */
637
    public function testBeanWithoutStatus()
638
    {
639
        $object = new TDBMObject('users');
640
        $object->setProperty('login', 'john.doe');
641
        $object->setProperty('country_id', 3);
642
        $object->setProperty('name', 'John Doe', 'person');
643
        $object->setProperty('email', '[email protected]', 'contact');
644
        $object->_setStatus(null);
645
        $this->tdbmService->save($object);
646
    }
647
648
    public function testFindObjectsFromSql()
649
    {
650
        $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',
651
            'rights.label = :right', array('right' => 'CAN_SING'), 'name DESC');
652
        $this->assertCount(2, $roles);
653
        $this->assertInstanceOf(AbstractTDBMObject::class, $roles[0]);
654
    }
655
656
    /**
657
     * @expectedException \TheCodingMachine\TDBM\TDBMException
658
     *
659
     * @throws TDBMException
660
     */
661
    public function testFindObjectsFromSqlBadTableName()
662
    {
663
        $this->tdbmService->findObjectsFromSql('#{azerty', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
664
            'rights.label = :right', array('right' => 'CAN_SING'), 'name DESC');
665
    }
666
667
    /**
668
     * @expectedException \TheCodingMachine\TDBM\TDBMException
669
     *
670
     * @throws TDBMException
671
     */
672
    public function testFindObjectsFromSqlGroupBy()
673
    {
674
        $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',
675
            'rights.label = :right GROUP BY roles.name', array('right' => 'CAN_SING'), 'name DESC');
676
        $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...
677
    }
678
679
    public function testFindObjectFromSql()
680
    {
681
        $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',
682
            'rights.label = :right AND name = :name', array('right' => 'CAN_SING', 'name' => 'Singers'));
683
        $this->assertInstanceOf(AbstractTDBMObject::class, $role);
684
    }
685
686
    /**
687
     * @expectedException \TheCodingMachine\TDBM\DuplicateRowException
688
     *
689
     * @throws DuplicateRowException
690
     */
691
    public function testFindObjectFromSqlException()
692
    {
693
        $this->tdbmService->findObjectFromSql('roles', 'roles JOIN roles_rights ON roles.id = roles_rights.role_id JOIN rights ON rights.label = roles_rights.right_label',
694
            'rights.label = :right', array('right' => 'CAN_SING'));
695
    }
696
697 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...
698
    {
699
        $users = $this->tdbmService->findObjectsFromSql('person', 'person', 'name LIKE :name OR name LIKE :name2',
700
            array('name' => 'Robert Marley', 'name2' => 'Bill Shakespeare'), null, null, TDBMObject::class);
701
        $this->assertCount(2, $users);
702
        $this->assertSame('robert.marley', $users[0]->getProperty('login', 'users'));
703
    }
704
705 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...
706
    {
707
        $users = $this->tdbmService->findObjectsFromSql('users', 'users', 'login LIKE :login OR login LIKE :login2',
708
            array('login' => 'robert.marley', 'login2' => 'bill.shakespeare'), null, null, TDBMObject::class);
709
        $this->assertCount(2, $users);
710
        $this->assertSame('Robert Marley', $users[0]->getProperty('name', 'person'));
711
    }
712
713
    public function testLogger()
714
    {
715
        $arrayLogger = new ArrayLogger();
716
        $tdbmService = new TDBMService(new Configuration('TheCodingMachine\\TDBM\\Test\\Dao\\Bean', 'TheCodingMachine\\TDBM\\Test\\Dao', $this->dbConnection, $this->getNamingStrategy(), null, null, $arrayLogger));
717
718
        $tdbmService->setLogLevel(LogLevel::DEBUG);
719
        $beans = $tdbmService->findObjects('contact', null, [], 'contact.id ASC', [], null, TDBMObject::class);
720
        $beans->first();
721
722
        $this->assertNotEmpty($arrayLogger->get());
723
    }
724
725
    public function testFindObjectsCountWithOneToManyLink()
726
    {
727
        $countries = $this->tdbmService->findObjects('country', "users.status = 'on' OR users.status = 'off'");
728
729
        $this->assertEquals(3, $countries->count());
730
    }
731
732
    public function testFindObjectsFromSqlCountWithOneToManyLink()
733
    {
734
        $countries = $this->tdbmService->findObjectsFromSql('country', 'country LEFT JOIN users ON country.id = users.country_id', "users.status = 'on' OR users.status = 'off'");
735
736
        $this->assertEquals(3, $countries->count());
737
    }
738
739
    /*
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...
740
        public function testObjectAsFilter() {
741
            $dpt = $this->tdbmService->getObject('departements', 1);
742
            $dpt2 =  $this->tdbmService->getObject('departements', $dpt);
743
            $this->assertEquals($dpt, $dpt2);
744
        }
745
746
        public function testOneWayAndTheOpposite() {
747
            $this->tdbmService->getObjects('utilisateur_entite', new EqualFilter('entites', 'appellation', 'foo'));
748
            $this->tdbmService->getObjects('entites', new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'));
749
        }
750
751
        public function testOneWayAndTheOpposite2() {
752
            $this->tdbmService->getObjects('utilisateur_entite', new EqualFilter('departements', 'id', '1'));
753
            $this->tdbmService->getObjects('departements', new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'));
754
        }
755
756
        public function testOneWayAndTheOpposite3() {
757
            $this->tdbmService->getObjects('utilisateur_entite',
758
                    [
759
                    new EqualFilter('entites', 'appellation', 1),
760
                    ]
761
            );
762
            $this->tdbmService->getObjects('entites', [
763
                        new EqualFilter('departements', 'id', 1),
764
                        new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'),
765
                    ]
766
            );
767
        }
768
769
        public function testOneWayAndTheOpposite4() {
770
            $this->tdbmService->getObjects('utilisateur_entite', null,
771
                    [
772
                    new OrderByColumn('entites', 'appellation', 'ASC'),
773
                    ]
774
            );
775
            $this->tdbmService->getObjects('entites', new EqualFilter('utilisateur_entite', 'id_utilisateur', '1'),
776
                    [
777
                    new OrderByColumn('departements', 'id', 'ASC')
778
                    ]
779
            );
780
        }
781
782
        public function testTDBMObjectArrayMultipleForeach() {
783
            $results = $this->tdbmService->getObjects('departements');
784
            $this->assertTrue(is_array($results));
785
            $count = 0;
786
            foreach ($results as $result) {
787
                $count++;
788
            }
789
            $this->assertEquals(95, $count);
790
791
            $count = 0;
792
            foreach ($results as $result) {
793
                $count++;
794
            }
795
            $this->assertEquals(95, $count);
796
797
        }
798
799
        public function testTDBMObjectsCursorMode() {
800
            $this->tdbmService->setFetchMode(TDBMService::MODE_CURSOR);
801
            $results = $this->tdbmService->getObjects('departements');
802
803
            $count = 0;
804
            foreach ($results as $result) {
805
                $count++;
806
            }
807
            $this->assertEquals(95, $count);
808
        }
809
810
        public function testTDBMObjectCursorMode() {
811
            $this->tdbmService->setFetchMode(TDBMService::MODE_CURSOR);
812
            $result = $this->tdbmService->getObject('departements', array(new EqualFilter('departements', 'id', 1)));
813
814
            $this->assertEquals("Ain", $result->nom);
815
        }
816
817
818
        public function testTDBMObjectArrayCount() {
819
            $results = $this->tdbmService->getObjects('departements');
820
            $this->assertEquals(95, count($results));
821
            $this->assertEquals(95, count($results));
822
823
        }
824
825
826
        public function testTDBMObjectArrayAccessByKey() {
827
            $results = $this->tdbmService->getObjects('departements');
828
829
            $this->assertEquals("Alpes Maritimes", $results[5]->nom);
830
        }
831
832
        public function testTDBMObjectArrayCountAfterForeach() {
833
            $results = $this->tdbmService->getObjects('departements');
834
            foreach ($results as $result) {
835
                // Do nothing
836
            }
837
            $this->assertEquals(95, count($results));
838
        }
839
840
        public function testStorage() {
841
            $results = $this->tdbmService->getObjects('departements');
842
843
            $result = $this->tdbmService->getObject('departements', 1);
844
845
            $this->assertTrue($results[0] === $result);
846
        }
847
848
        public function testCloneTDBMObject()
849
        {
850
            // Create a new object
851
            $object = $this->tdbmService->getNewObject('departements');
852
            $object->id_region = 22;
853
            $object->numero = '100';
854
            $object->nom = 'test';
855
            $object->nom_web = 'test';
856
            // Save the object
857
            $object->save();
858
859
            // Try to clone the object
860
            $cloneObject = clone $object;
861
            // Save the cloned object
862
            $cloneObject->save();
863
864
            $this->assertNotEquals($object->id, $cloneObject->id);
865
            $this->assertEquals($object->nom, $cloneObject->nom);
866
867
            $this->tdbmService->deleteObject($object);
868
            $this->tdbmService->deleteObject($cloneObject);
869
        }
870
    */
871
}
872