Completed
Push — master ( 0f37d2...f29122 )
by David
15s
created

TDBMDaoGeneratorTest::testFindOrderBy()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 13

Duplication

Lines 18
Ratio 100 %

Importance

Changes 0
Metric Value
dl 18
loc 18
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 13
nc 2
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 Doctrine\Common\Cache\ArrayCache;
24
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
25
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
26
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
27
use Ramsey\Uuid\Uuid;
28
use TheCodingMachine\TDBM\Dao\TestCountryDao;
29
use TheCodingMachine\TDBM\Dao\TestRoleDao;
30
use TheCodingMachine\TDBM\Dao\TestUserDao;
31
use TheCodingMachine\TDBM\Test\Dao\AllNullableDao;
32
use TheCodingMachine\TDBM\Test\Dao\AnimalDao;
33
use TheCodingMachine\TDBM\Test\Dao\Bean\AllNullableBean;
34
use TheCodingMachine\TDBM\Test\Dao\Bean\Article2Bean;
35
use TheCodingMachine\TDBM\Test\Dao\Bean\ArticleBean;
36
use TheCodingMachine\TDBM\Test\Dao\Bean\BoatBean;
37
use TheCodingMachine\TDBM\Test\Dao\Bean\CatBean;
38
use TheCodingMachine\TDBM\Test\Dao\Bean\CategoryBean;
39
use TheCodingMachine\TDBM\Test\Dao\Bean\CountryBean;
40
use TheCodingMachine\TDBM\Test\Dao\Bean\DogBean;
41
use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\UserBaseBean;
42
use TheCodingMachine\TDBM\Test\Dao\Bean\PersonBean;
43
use TheCodingMachine\TDBM\Test\Dao\Bean\RoleBean;
44
use TheCodingMachine\TDBM\Test\Dao\Bean\UserBean;
45
use TheCodingMachine\TDBM\Test\Dao\BoatDao;
46
use TheCodingMachine\TDBM\Test\Dao\CatDao;
47
use TheCodingMachine\TDBM\Test\Dao\CategoryDao;
48
use TheCodingMachine\TDBM\Test\Dao\ContactDao;
49
use TheCodingMachine\TDBM\Test\Dao\CountryDao;
50
use TheCodingMachine\TDBM\Test\Dao\DogDao;
51
use TheCodingMachine\TDBM\Test\Dao\Generated\UserBaseDao;
52
use TheCodingMachine\TDBM\Test\Dao\RefNoPrimKeyDao;
53
use TheCodingMachine\TDBM\Test\Dao\RoleDao;
54
use TheCodingMachine\TDBM\Test\Dao\UserDao;
55
use TheCodingMachine\TDBM\Utils\PathFinder\NoPathFoundException;
56
use TheCodingMachine\TDBM\Utils\TDBMDaoGenerator;
57
use Symfony\Component\Process\Process;
58
59
class TDBMDaoGeneratorTest extends TDBMAbstractServiceTest
60
{
61
    /** @var TDBMDaoGenerator $tdbmDaoGenerator */
62
    protected $tdbmDaoGenerator;
63
64
    private $rootPath;
65
66
    protected function setUp()
67
    {
68
        parent::setUp();
69
        $schemaManager = $this->tdbmService->getConnection()->getSchemaManager();
70
        $schemaAnalyzer = new SchemaAnalyzer($schemaManager);
71
        $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer);
72
        $this->tdbmDaoGenerator = new TDBMDaoGenerator($this->getConfiguration(), $tdbmSchemaAnalyzer);
73
        $this->rootPath = __DIR__.'/../';
74
        //$this->tdbmDaoGenerator->setComposerFile($this->rootPath.'composer.json');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
75
    }
76
77
    public function testDaoGeneration()
78
    {
79
        // Remove all previously generated files.
80
        $this->recursiveDelete($this->rootPath.'src/Test/Dao/');
81
82
        $this->tdbmDaoGenerator->generateAllDaosAndBeans();
83
84
        // Let's require all files to check they are valid PHP!
85
        // Test the daoFactory
86
        require_once $this->rootPath.'src/Test/Dao/Generated/DaoFactory.php';
87
        // Test the others
88
89
        $beanDescriptors = $this->getDummyGeneratorListener()->getBeanDescriptors();
90
91
        foreach ($beanDescriptors as $beanDescriptor) {
92
            $daoName = $beanDescriptor->getDaoClassName();
93
            $daoBaseName = $beanDescriptor->getBaseDaoClassName();
94
            $beanName = $beanDescriptor->getBeanClassName();
95
            $baseBeanName = $beanDescriptor->getBaseBeanClassName();
96
            require_once $this->rootPath.'src/Test/Dao/Bean/Generated/'.$baseBeanName.'.php';
97
            require_once $this->rootPath.'src/Test/Dao/Bean/'.$beanName.'.php';
98
            require_once $this->rootPath.'src/Test/Dao/Generated/'.$daoBaseName.'.php';
99
            require_once $this->rootPath.'src/Test/Dao/'.$daoName.'.php';
100
        }
101
102
        // Check that pivot tables do not generate DAOs or beans.
103
        $this->assertFalse(class_exists('TheCodingMachine\\TDBM\\Test\\Dao\\RolesRightDao'));
104
    }
105
106
    public function testGenerationException()
107
    {
108
        $configuration = new Configuration('UnknownVendor\\Dao', 'UnknownVendor\\Bean', self::getConnection(), $this->getNamingStrategy());
109
110
        $schemaManager = $this->tdbmService->getConnection()->getSchemaManager();
111
        $schemaAnalyzer = new SchemaAnalyzer($schemaManager);
112
        $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer);
113
        $tdbmDaoGenerator = new TDBMDaoGenerator($configuration, $tdbmSchemaAnalyzer);
114
        $this->rootPath = __DIR__.'/../../../../';
115
        //$tdbmDaoGenerator->setComposerFile($this->rootPath.'composer.json');
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% 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...
116
117
        $this->expectException(NoPathFoundException::class);
118
        $tdbmDaoGenerator->generateAllDaosAndBeans();
119
    }
120
121
    /**
122
     * Delete a file or recursively delete a directory.
123
     *
124
     * @param string $str Path to file or directory
125
     * @return bool
126
     */
127
    private function recursiveDelete(string $str) : bool
128
    {
129
        if (is_file($str)) {
130
            return @unlink($str);
131
        } elseif (is_dir($str)) {
132
            $scan = glob(rtrim($str, '/') . '/*');
133
            foreach ($scan as $index => $path) {
134
                $this->recursiveDelete($path);
135
            }
136
137
            return @rmdir($str);
138
        }
139
        return false;
140
    }
141
142
    /**
143
     * @depends testDaoGeneration
144
     */
145
    public function testGetBeanClassName()
146
    {
147
        $this->assertEquals(UserBean::class, $this->tdbmService->getBeanClassName('users'));
148
    }
149
150
    /**
151
     * @depends testDaoGeneration
152
     */
153
    public function testGetBeanClassNameException()
154
    {
155
        $this->expectException(TDBMInvalidArgumentException::class);
156
        $this->tdbmService->getBeanClassName('not_exists');
157
    }
158
159
    /**
160
     * @depends testDaoGeneration
161
     */
162
    public function testGeneratedGetById()
163
    {
164
        $contactDao = new ContactDao($this->tdbmService);
165
        $contactBean = $contactDao->getById(1);
166
        $this->assertEquals(1, $contactBean->getId());
167
        $this->assertInstanceOf('\\DateTimeInterface', $contactBean->getCreatedAt());
168
169
        // FIXME: Question: que faire du paramètre stockage "UTC"????
170
    }
171
172
    /**
173
     * @depends testDaoGeneration
174
     */
175
    public function testGeneratedGetByIdLazyLoaded()
176
    {
177
        $roleDao = new RoleDao($this->tdbmService);
178
        $roleBean = $roleDao->getById(1, true);
179
        $this->assertEquals(1, $roleBean->getId());
180
        $this->assertInstanceOf('\\DateTimeInterface', $roleBean->getCreatedAt());
181
182
        $roleBean2 = $roleDao->getById(1, true);
183
        $this->assertTrue($roleBean === $roleBean2);
184
    }
185
186
    /**
187
     * @depends testDaoGeneration
188
     */
189
    public function testDefaultValueOnNewBean()
190
    {
191
        $roleBean = new RoleBean('my_role');
192
        $this->assertEquals(1, $roleBean->getStatus());
193
    }
194
195
    /**
196
     * @depends testDaoGeneration
197
     */
198 View Code Duplication
    public function testForeignKeyInBean()
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...
199
    {
200
        $userDao = new UserDao($this->tdbmService);
201
        $userBean = $userDao->getById(1);
202
        $country = $userBean->getCountry();
203
204
        $this->assertEquals('UK', $country->getLabel());
205
206
        $userBean2 = $userDao->getById(1);
207
        $this->assertTrue($userBean === $userBean2);
208
209
        $contactDao = new ContactDao($this->tdbmService);
210
        $contactBean = $contactDao->getById(1);
211
212
        $this->assertTrue($userBean === $contactBean);
213
    }
214
215
    /**
216
     * @depends testDaoGeneration
217
     */
218
    public function testNewBeans()
219
    {
220
        $countryDao = new CountryDao($this->tdbmService);
221
        $userDao = new UserDao($this->tdbmService);
222
        $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe');
223
        $userBean->setOrder(1); // Let's set a "protected keyword" column.
224
225
        $userDao->save($userBean);
226
227
        $this->assertNull($userBean->getManager());
228
    }
229
230
    /**
231
     * @depends testDaoGeneration
232
     */
233
    public function testDateTimeImmutableGetter()
234
    {
235
        $userDao = new UserDao($this->tdbmService);
236
        $user = $userDao->getById(1);
237
238
        $this->assertInstanceOf('\DateTimeImmutable', $user->getCreatedAt());
239
    }
240
241
    /**
242
     * @depends testDaoGeneration
243
     */
244 View Code Duplication
    public function testAssigningNewBeans()
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...
245
    {
246
        $userDao = new UserDao($this->tdbmService);
247
        $countryBean = new CountryBean('Mexico');
248
        $userBean = new UserBean('Speedy Gonzalez', '[email protected]', $countryBean, 'speedy.gonzalez');
249
        $this->assertEquals($countryBean, $userBean->getCountry());
250
251
        $userDao->save($userBean);
252
    }
253
254
    /**
255
     * @depends testAssigningNewBeans
256
     */
257
    public function testUpdatingProtectedColumn()
258
    {
259
        $userDao = new UserDao($this->tdbmService);
260
        $userBean = $userDao->findOneByLogin('speedy.gonzalez');
261
        $userBean->setOrder(2);
262
        $userDao->save($userBean);
263
    }
264
265
    /**
266
     * @depends testDaoGeneration
267
     */
268 View Code Duplication
    public function testAssigningExistingRelationship()
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...
269
    {
270
        $userDao = new UserDao($this->tdbmService);
271
        $user = $userDao->getById(1);
272
        $countryDao = new CountryDao($this->tdbmService);
273
        $country = $countryDao->getById(2);
274
275
        $user->setCountry($country);
276
        $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus());
277
    }
278
279
    /**
280
     * @depends testDaoGeneration
281
     */
282
    public function testDirectReversedRelationship()
283
    {
284
        $countryDao = new CountryDao($this->tdbmService);
285
        $country = $countryDao->getById(1);
286
        $users = $country->getUsers();
287
288
        $arr = $users->toArray();
289
290
        $this->assertCount(1, $arr);
291
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[0]);
292
        $this->assertEquals('jean.dupont', $arr[0]->getLogin());
293
294
        $newUser = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
0 ignored issues
show
Unused Code introduced by
$newUser 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...
295
        $users = $country->getUsers();
296
297
        $arr = $users->toArray();
298
299
        $this->assertCount(2, $arr);
300
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[1]);
301
        $this->assertEquals('speedy.gonzalez', $arr[1]->getLogin());
302
    }
303
304
    /**
305
     * @depends testDaoGeneration
306
     */
307
    public function testDeleteInDirectReversedRelationship()
308
    {
309
        $countryDao = new CountryDao($this->tdbmService);
310
        $country = $countryDao->getById(1);
311
312
        $userDao = new UserDao($this->tdbmService);
313
        $newUser = new UserBean('John Snow', '[email protected]', $country, 'john.snow');
314
        $userDao->save($newUser);
315
316
        $users = $country->getUsers();
317
318
        $arr = $users->toArray();
319
320
        $this->assertCount(2, $arr);
321
322
        $userDao->delete($arr[1]);
323
324
        $users = $country->getUsers();
325
        $arr = $users->toArray();
326
        $this->assertCount(1, $arr);
327
    }
328
329
    /**
330
     * @depends testDaoGeneration
331
     */
332
    public function testJointureGetters()
333
    {
334
        $roleDao = new RoleDao($this->tdbmService);
335
        $role = $roleDao->getById(1);
336
        $users = $role->getUsers();
337
338
        $this->assertCount(2, $users);
339
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $users[0]);
340
341
        $rights = $role->getRights();
342
343
        $this->assertCount(2, $rights);
344
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RightBean', $rights[0]);
345
    }
346
347
    /**
348
     * @depends testDaoGeneration
349
     */
350
    public function testNewBeanConstructor()
351
    {
352
        $role = new RoleBean('Newrole');
353
        $this->assertEquals(TDBMObjectStateEnum::STATE_DETACHED, $role->_getStatus());
354
    }
355
356
    /**
357
     * @depends testDaoGeneration
358
     */
359
    public function testJointureAdderOnNewBean()
360
    {
361
        $countryDao = new CountryDao($this->tdbmService);
362
        $country = $countryDao->getById(1);
363
        $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
364
        $role = new RoleBean('Mouse');
365
        $user->addRole($role);
366
        $roles = $user->getRoles();
367
        $this->assertCount(1, $roles);
368
        $role = $roles[0];
369
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RoleBean', $role);
370
        $users = $role->getUsers();
371
        $this->assertCount(1, $users);
372
        $this->assertEquals($user, $users[0]);
373
374
        $role->removeUser($user);
375
        $this->assertCount(0, $role->getUsers());
376
        $this->assertCount(0, $user->getRoles());
377
    }
378
379
    /**
380
     * @depends testDaoGeneration
381
     */
382 View Code Duplication
    public function testJointureDeleteBeforeGetters()
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...
383
    {
384
        $roleDao = new RoleDao($this->tdbmService);
385
        $userDao = new UserDao($this->tdbmService);
386
        $role = $roleDao->getById(1);
387
        $user = $userDao->getById(1);
388
389
        // We call removeUser BEFORE calling getUsers
390
        // This should work as expected.
391
        $role->removeUser($user);
392
        $users = $role->getUsers();
393
394
        $this->assertCount(1, $users);
395
    }
396
397
    /**
398
     * @depends testDaoGeneration
399
     */
400
    public function testJointureMultiAdd()
401
    {
402
        $countryDao = new CountryDao($this->tdbmService);
403
        $country = $countryDao->getById(1);
404
        $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
405
        $role = new RoleBean('Mouse');
406
        $user->addRole($role);
407
        $role->addUser($user);
408
        $user->addRole($role);
409
410
        $this->assertCount(1, $user->getRoles());
411
    }
412
413
    /**
414
     * Step 1: we remove the role 1 from user 1 but save role 1.
415
     * Expected result: no save done.
416
     *
417
     * @depends testDaoGeneration
418
     */
419
    public function testJointureSave1()
420
    {
421
        $roleDao = new RoleDao($this->tdbmService);
422
        $role = $roleDao->getById(1);
423
        $userDao = new UserDao($this->tdbmService);
424
        $user = $userDao->getById(1);
425
426
        $this->assertTrue($user->hasRole($role));
427
        $this->assertTrue($role->hasUser($user));
428
        $user->removeRole($role);
429
        $this->assertFalse($user->hasRole($role));
430
        $this->assertFalse($role->hasUser($user));
431
        $roleDao->save($role);
432
433
        $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus());
434
        $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus());
435
    }
436
437
    /**
438
     * Step 2: we check that nothing was saved
439
     * Expected result: no save done.
440
     *
441
     * @depends testJointureSave1
442
     */
443
    public function testJointureSave2()
444
    {
445
        $roleDao = new RoleDao($this->tdbmService);
446
        $role = $roleDao->getById(1);
447
        $this->assertCount(2, $role->getUsers());
448
    }
449
450
    /**
451
     * Step 3: we remove the role 1 from user 1 and save user 1.
452
     * Expected result: save done.
453
     *
454
     * @depends testJointureSave2
455
     */
456
    public function testJointureSave3()
457
    {
458
        $roleDao = new RoleDao($this->tdbmService);
459
        $role = $roleDao->getById(1);
460
        $userDao = new UserDao($this->tdbmService);
461
        $user = $userDao->getById(1);
462
463
        $this->assertCount(1, $user->getRoles());
464
        $user->removeRole($role);
465
        $this->assertCount(0, $user->getRoles());
466
        $userDao->save($user);
467
        $this->assertCount(0, $user->getRoles());
468
    }
469
470
    /**
471
     * Step 4: we check that save was done
472
     * Expected result: save done.
473
     *
474
     * @depends testJointureSave3
475
     */
476 View Code Duplication
    public function testJointureSave4()
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...
477
    {
478
        $roleDao = new RoleDao($this->tdbmService);
479
        $role = $roleDao->getById(1);
480
        $this->assertCount(1, $role->getUsers());
481
        $userDao = new UserDao($this->tdbmService);
482
        $user = $userDao->getById(1);
483
        $this->assertCount(0, $user->getRoles());
484
    }
485
486
    /**
487
     * Step 5: we add the role 1 from user 1 and save user 1.
488
     * Expected result: save done.
489
     *
490
     * @depends testJointureSave4
491
     */
492 View Code Duplication
    public function testJointureSave5()
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...
493
    {
494
        $roleDao = new RoleDao($this->tdbmService);
495
        $role = $roleDao->getById(1);
496
        $userDao = new UserDao($this->tdbmService);
497
        $user = $userDao->getById(1);
498
499
        $user->addRole($role);
500
        $this->assertCount(1, $user->getRoles());
501
        $userDao->save($user);
502
    }
503
504
    /**
505
     * Step 6: we check that save was done
506
     * Expected result: save done.
507
     *
508
     * @depends testJointureSave5
509
     */
510 View Code Duplication
    public function testJointureSave6()
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...
511
    {
512
        $roleDao = new RoleDao($this->tdbmService);
513
        $role = $roleDao->getById(1);
514
        $this->assertCount(2, $role->getUsers());
515
        $userDao = new UserDao($this->tdbmService);
516
        $user = $userDao->getById(1);
517
        $this->assertCount(1, $user->getRoles());
518
    }
519
520
    /**
521
     * Step 7: we add a new role to user 1 and save user 1.
522
     * Expected result: save done, including the new role.
523
     *
524
     * @depends testJointureSave6
525
     */
526
    public function testJointureSave7()
527
    {
528
        $role = new RoleBean('my new role');
529
        $userDao = new UserDao($this->tdbmService);
530
        $user = $userDao->getById(1);
531
532
        $user->addRole($role);
533
        $userDao->save($user);
534
535
        $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus());
536
    }
537
538
    /**
539
     * Step 8: we check that save was done
540
     * Expected result: save done.
541
     *
542
     * @depends testJointureSave7
543
     */
544 View Code Duplication
    public function testJointureSave8()
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...
545
    {
546
        $roleDao = new RoleDao($this->tdbmService);
547
        $userDao = new UserDao($this->tdbmService);
548
        $user = $userDao->getById(1);
549
550
        $roles = $user->getRoles();
551
        foreach ($roles as $role) {
552
            if ($role->getName() === 'my new role') {
553
                $selectedRole = $role;
554
                break;
555
            }
556
        }
557
        $this->assertNotNull($selectedRole);
0 ignored issues
show
Bug introduced by
The variable $selectedRole 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...
558
559
        $this->assertCount(2, $user->getRoles());
560
561
        // Expected: relationship removed!
562
        $roleDao->delete($selectedRole);
563
564
        $this->assertCount(1, $user->getRoles());
565
    }
566
567
    /**
568
     * Step 9: Let's test the setXXX method.
569
     *
570
     * @depends testJointureSave8
571
     */
572
    public function testJointureSave9()
573
    {
574
        $roleDao = new RoleDao($this->tdbmService);
575
        $userDao = new UserDao($this->tdbmService);
576
        $user = $userDao->getById(1);
577
578
        // At this point, user 1 is linked to role 1.
579
        // Let's bind it to role 2.
580
        $user->setRoles([$roleDao->getById(2)]);
581
        $userDao->save($user);
582
    }
583
584
    /**
585
     * Step 10: Let's check results of 9.
586
     *
587
     * @depends testJointureSave9
588
     */
589
    public function testJointureSave10()
590
    {
591
        $userDao = new UserDao($this->tdbmService);
592
        $user = $userDao->getById(1);
593
594
        $roles = $user->getRoles();
595
596
        $this->assertCount(1, $roles);
597
        $this->assertEquals(2, $roles[0]->getId());
598
    }
599
600
    /**
601
     * @depends testDaoGeneration
602
     */
603 View Code Duplication
    public function testFindOrderBy()
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...
604
    {
605
        $userDao = new TestUserDao($this->tdbmService);
606
        $users = $userDao->getUsersByAlphabeticalOrder();
607
608
        $this->assertCount(6, $users);
609
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
610
        $this->assertEquals('jean.dupont', $users[1]->getLogin());
611
612
        $users = $userDao->getUsersByCountryOrder();
613
        $this->assertCount(6, $users);
614
        $countryName1 = $users[0]->getCountry()->getLabel();
615
        for ($i = 1; $i < 6; $i++) {
616
            $countryName2 = $users[$i]->getCountry()->getLabel();
617
            $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2));
618
            $countryName1 = $countryName2;
619
        }
620
    }
621
622
    /**
623
     * @depends testDaoGeneration
624
     */
625 View Code Duplication
    public function testFindFromSqlOrderBy()
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...
626
    {
627
        $userDao = new TestUserDao($this->tdbmService);
628
        $users = $userDao->getUsersFromSqlByAlphabeticalOrder();
629
630
        $this->assertCount(6, $users);
631
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
632
        $this->assertEquals('jean.dupont', $users[1]->getLogin());
633
634
        $users = $userDao->getUsersFromSqlByCountryOrder();
635
        $this->assertCount(6, $users);
636
        $countryName1 = $users[0]->getCountry()->getLabel();
637
        for ($i = 1; $i < 6; $i++) {
638
            $countryName2 = $users[$i]->getCountry()->getLabel();
639
            $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2));
640
            $countryName1 = $countryName2;
641
        }
642
    }
643
644
    /**
645
     * @depends testDaoGeneration
646
     */
647
    public function testFindFromSqlOrderByJoinRole()
648
    {
649
        $roleDao = new TestRoleDao($this->tdbmService);
650
        $roles = $roleDao->getRolesByRightCanSing('roles.name DESC');
651
652
        $this->assertCount(2, $roles);
653
        $this->assertEquals('Singers', $roles[0]->getName());
654
        $this->assertEquals('Admins', $roles[1]->getName());
655
    }
656
657
    /**
658
     * @depends testDaoGeneration
659
     */
660
    public function testFindFromRawSqlOrderByUserCount()
661
    {
662
        $countryDao = new TestCountryDao($this->tdbmService);
663
        $countries = $countryDao->getCountriesByUserCount();
664
665
        $this->assertCount(4, $countries);
666
        for ($i = 1; $i < count($countries); $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...
667
            $this->assertLessThanOrEqual($countries[$i - 1]->getUsers()->count(), $countries[$i]->getUsers()->count());
668
        }
669
    }
670
671
    /**
672
     * @depends testDaoGeneration
673
     */
674 View Code Duplication
    public function testFindFilters()
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...
675
    {
676
        $userDao = new TestUserDao($this->tdbmService);
677
        $users = $userDao->getUsersByLoginStartingWith('bill');
678
679
        $this->assertCount(1, $users);
680
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
681
    }
682
683
    /**
684
     * @expectedException \TheCodingMachine\TDBM\TDBMException
685
     * @depends testDaoGeneration
686
     */
687
    public function testFindMode()
688
    {
689
        $userDao = new TestUserDao($this->tdbmService);
690
        $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR);
691
692
        $users[0];
693
    }
694
695
    /**
696
     * @depends testDaoGeneration
697
     */
698
    public function testFindAll()
699
    {
700
        $userDao = new TestUserDao($this->tdbmService);
701
        $users = $userDao->findAll();
702
703
        $this->assertCount(6, $users);
704
    }
705
706
    /**
707
     * @depends testDaoGeneration
708
     */
709
    public function testFindOne()
710
    {
711
        $userDao = new TestUserDao($this->tdbmService);
712
        $user = $userDao->getUserByLogin('bill.shakespeare');
713
714
        $this->assertEquals('bill.shakespeare', $user->getLogin());
715
    }
716
717
    /**
718
     * @depends testDaoGeneration
719
     */
720
    public function testJsonEncodeBean()
721
    {
722
        $userDao = new TestUserDao($this->tdbmService);
723
        $user = $userDao->getUserByLogin('bill.shakespeare');
724
725
        $jsonEncoded = json_encode($user);
726
        $userDecoded = json_decode($jsonEncoded, true);
727
728
        $this->assertEquals('bill.shakespeare', $userDecoded['login']);
729
730
        // test serialization of dates.
731
        $this->assertTrue(is_string($userDecoded['createdAt']));
732
        $this->assertEquals('2015-10-24', (new \DateTimeImmutable($userDecoded['createdAt']))->format('Y-m-d'));
733
        $this->assertNull($userDecoded['modifiedAt']);
734
735
        // testing many to 1 relationships
736
        $this->assertEquals('UK', $userDecoded['country']['label']);
737
738
        // testing many to many relationships
739
        $this->assertCount(1, $userDecoded['roles']);
740
        $this->assertArrayNotHasKey('users', $userDecoded['roles'][0]);
741
        $this->assertArrayNotHasKey('rights', $userDecoded['roles'][0]);
742
    }
743
744
    /**
745
     * @depends testDaoGeneration
746
     */
747
    public function testNullableForeignKey()
748
    {
749
        $userDao = new TestUserDao($this->tdbmService);
750
        $user = $userDao->getUserByLogin('john.smith');
751
752
        $this->assertNull(null, $user->getManager());
753
754
        $jsonEncoded = json_encode($user);
755
        $userDecoded = json_decode($jsonEncoded, true);
756
757
        $this->assertNull(null, $userDecoded['manager']);
758
    }
759
760
    /**
761
     * Test that setting (and saving) objects' references (foreign keys relations) to null is working.
762
     *
763
     * @depends testDaoGeneration
764
     */
765
    public function testSetToNullForeignKey()
766
    {
767
        $userDao = new TestUserDao($this->tdbmService);
768
        $user = $userDao->getUserByLogin('john.smith');
769
        $manager = $userDao->getUserByLogin('jean.dupont');
770
771
        $user->setManager($manager);
772
        $userDao->save($user);
773
774
        $user->setManager(null);
775
        $userDao->save($user);
776
    }
777
778
    /**
779
     * @depends testDaoGeneration
780
     * @expectedException \Mouf\Database\SchemaAnalyzer\SchemaAnalyzerTableNotFoundException
781
     * @expectedExceptionMessage Could not find table 'contacts'. Did you mean 'contact'?
782
     */
783
    public function testQueryOnWrongTableName()
784
    {
785
        $userDao = new TestUserDao($this->tdbmService);
786
        $users = $userDao->getUsersWrongTableName();
787
        $users->count();
788
    }
789
790
    /**
791
     * @depends testDaoGeneration
792
     */
793
    /*public function testQueryNullForeignKey()
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
794
    {
795
        $userDao = new TestUserDao($this->tdbmService);
796
        $users = $userDao->getUsersByManagerId(null);
797
        $this->assertCount(3, $users);
798
    }*/
799
800
    /**
801
     * @depends testDaoGeneration
802
     */
803
    public function testInnerJsonEncode()
804
    {
805
        $userDao = new TestUserDao($this->tdbmService);
806
        $user = $userDao->getUserByLogin('bill.shakespeare');
807
808
        $jsonEncoded = json_encode(['user' => $user]);
809
        $msgDecoded = json_decode($jsonEncoded, true);
810
811
        $this->assertEquals('bill.shakespeare', $msgDecoded['user']['login']);
812
    }
813
814
    /**
815
     * @depends testDaoGeneration
816
     */
817 View Code Duplication
    public function testArrayJsonEncode()
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...
818
    {
819
        $userDao = new TestUserDao($this->tdbmService);
820
        $users = $userDao->getUsersByLoginStartingWith('bill');
821
822
        $jsonEncoded = json_encode($users);
823
        $msgDecoded = json_decode($jsonEncoded, true);
824
825
        $this->assertCount(1, $msgDecoded);
826
    }
827
828
    /**
829
     * @depends testDaoGeneration
830
     */
831 View Code Duplication
    public function testCursorJsonEncode()
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...
832
    {
833
        $userDao = new TestUserDao($this->tdbmService);
834
        $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR);
835
836
        $jsonEncoded = json_encode($users);
837
        $msgDecoded = json_decode($jsonEncoded, true);
838
839
        $this->assertCount(1, $msgDecoded);
840
    }
841
842
    /**
843
     * @depends testDaoGeneration
844
     */
845 View Code Duplication
    public function testPageJsonEncode()
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...
846
    {
847
        $userDao = new TestUserDao($this->tdbmService);
848
        $users = $userDao->getUsersByLoginStartingWith('bill');
849
850
        $jsonEncoded = json_encode($users->take(0, 1));
851
        $msgDecoded = json_decode($jsonEncoded, true);
852
853
        $this->assertCount(1, $msgDecoded);
854
    }
855
856
    /**
857
     * @depends testDaoGeneration
858
     */
859 View Code Duplication
    public function testFirst()
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...
860
    {
861
        $userDao = new TestUserDao($this->tdbmService);
862
        $users = $userDao->getUsersByLoginStartingWith('bill');
863
864
        $bill = $users->first();
865
        $this->assertEquals('bill.shakespeare', $bill->getLogin());
866
    }
867
868
    /**
869
     * @depends testDaoGeneration
870
     */
871
    public function testFirstNull()
872
    {
873
        $userDao = new TestUserDao($this->tdbmService);
874
        $users = $userDao->getUsersByLoginStartingWith('mike');
875
876
        $user = $users->first();
877
        $this->assertNull($user);
878
    }
879
880
    /**
881
     * @depends testDaoGeneration
882
     */
883
    public function testCloneBeanAttachedBean()
884
    {
885
        $userDao = new TestUserDao($this->tdbmService);
886
        $user = $userDao->getUserByLogin('bill.shakespeare');
887
        $this->assertEquals(4, $user->getId());
888
        $user2 = clone $user;
889
        $this->assertNull($user2->getId());
890
        $this->assertEquals('bill.shakespeare', $user2->getLogin());
891
        $this->assertEquals('Bill Shakespeare', $user2->getName());
892
        $this->assertEquals('UK', $user2->getCountry()->getLabel());
893
894
        // MANY 2 MANY must be duplicated
895
        $this->assertEquals('Writers', $user2->getRoles()[0]->getName());
896
897
        // Let's test saving this clone
898
        $user2->setLogin('william.shakespeare');
899
        $userDao->save($user2);
900
901
        $user3 = $userDao->getUserByLogin('william.shakespeare');
902
        $this->assertTrue($user3 === $user2);
903
        $userDao->delete($user3);
904
905
        // Finally, let's test the origin user still exists!
906
        $user4 = $userDao->getUserByLogin('bill.shakespeare');
907
        $this->assertEquals('bill.shakespeare', $user4->getLogin());
908
    }
909
910
    /**
911
     * @depends testDaoGeneration
912
     */
913
    public function testCloneNewBean()
914
    {
915
        $countryDao = new CountryDao($this->tdbmService);
916
        $roleDao = new RoleDao($this->tdbmService);
917
        $role = $roleDao->getById(1);
918
919
        $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe');
920
        $userBean->addRole($role);
921
922
        $user2 = clone $userBean;
923
924
        $this->assertNull($user2->getId());
925
        $this->assertEquals('john.doe', $user2->getLogin());
926
        $this->assertEquals('John Doe', $user2->getName());
927
        $this->assertEquals('UK', $user2->getCountry()->getLabel());
928
929
        // MANY 2 MANY must be duplicated
930
        $this->assertEquals($role->getName(), $user2->getRoles()[0]->getName());
931
    }
932
933
    /**
934
     * @depends testDaoGeneration
935
     */
936
    public function testCascadeDelete()
937
    {
938
        $userDao = new TestUserDao($this->tdbmService);
939
        $countryDao = new CountryDao($this->tdbmService);
940
941
        $spain = new CountryBean('Spain');
942
        $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $spain, 'manuel.sanchez');
943
944
        $countryDao->save($spain);
945
        $userDao->save($sanchez);
946
947
        $speedy2 = $userDao->getUserByLogin('manuel.sanchez');
948
        $this->assertTrue($sanchez === $speedy2);
949
950
        $exceptionTriggered = false;
951
        try {
952
            $countryDao->delete($spain);
953
        } catch (ForeignKeyConstraintViolationException $e) {
954
            $exceptionTriggered = true;
955
        }
956
        $this->assertTrue($exceptionTriggered);
957
958
        $countryDao->delete($spain, true);
959
960
        // Let's check that speed gonzalez was removed.
961
        $speedy3 = $userDao->getUserByLogin('manuel.sanchez');
962
        $this->assertNull($speedy3);
963
    }
964
965
    /**
966
     * @depends testDaoGeneration
967
     */
968
    public function testDiscardChanges()
969
    {
970
        $contactDao = new ContactDao($this->tdbmService);
971
        $contactBean = $contactDao->getById(1);
972
973
        $oldName = $contactBean->getName();
974
975
        $contactBean->setName('MyNewName');
976
977
        $contactBean->discardChanges();
978
979
        $this->assertEquals($oldName, $contactBean->getName());
980
    }
981
982
    /**
983
     * @expectedException \TheCodingMachine\TDBM\TDBMException
984
     * @depends testDaoGeneration
985
     */
986
    public function testDiscardChangesOnNewBeanFails()
987
    {
988
        $person = new PersonBean('John Foo', new \DateTimeImmutable());
989
        $person->discardChanges();
990
    }
991
992
    /**
993
     * @expectedException \TheCodingMachine\TDBM\TDBMException
994
     * @depends testDaoGeneration
995
     */
996
    public function testDiscardChangesOnDeletedBeanFails()
997
    {
998
        $userDao = new TestUserDao($this->tdbmService);
999
        $countryDao = new CountryDao($this->tdbmService);
1000
1001
        $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $countryDao->getById(1), 'manuel.sanchez');
1002
1003
        $userDao->save($sanchez);
1004
1005
        $userDao->delete($sanchez);
1006
1007
        // Cannot discard changes on a bean that is already deleted.
1008
        $sanchez->discardChanges();
1009
    }
1010
1011
    /**
1012
     * @depends testDaoGeneration
1013
     */
1014 View Code Duplication
    public function testUniqueIndexBasedSearch()
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...
1015
    {
1016
        $userDao = new UserDao($this->tdbmService);
1017
        $user = $userDao->findOneByLogin('bill.shakespeare');
1018
1019
        $this->assertEquals('bill.shakespeare', $user->getLogin());
1020
        $this->assertEquals('Bill Shakespeare', $user->getName());
1021
    }
1022
1023
    /**
1024
     * @depends testDaoGeneration
1025
     */
1026
    public function testFindOneByRetunsNull()
1027
    {
1028
        // Let's assert that the findOneBy... methods can return null.
1029
        $userDao = new UserDao($this->tdbmService);
1030
        $userBean = $userDao->findOneByLogin('not_exist');
1031
1032
        $this->assertNull($userBean);
1033
    }
1034
1035
    /**
1036
     * @depends testDaoGeneration
1037
     */
1038 View Code Duplication
    public function testMultiColumnsIndexBasedSearch()
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...
1039
    {
1040
        $countryDao = new CountryDao($this->tdbmService);
1041
        $userDao = new UserDao($this->tdbmService);
1042
        $users = $userDao->findByStatusAndCountry('on', $countryDao->getById(1));
1043
1044
        $this->assertEquals('jean.dupont', $users[0]->getLogin());
1045
    }
1046
1047
    /**
1048
     * @depends testDaoGeneration
1049
     */
1050
    public function testCreationInNullableDate()
1051
    {
1052
        $roleDao = new RoleDao($this->tdbmService);
1053
1054
        $role = new RoleBean('newbee');
1055
        $roleDao->save($role);
1056
1057
        $this->assertNull($role->getCreatedAt());
1058
    }
1059
1060
    /**
1061
     * @depends testDaoGeneration
1062
     */
1063
    public function testUpdateInNullableDate()
1064
    {
1065
        $roleDao = new RoleDao($this->tdbmService);
1066
1067
        $role = new RoleBean('newbee');
1068
        $roleDao->save($role);
1069
1070
        $role->setCreatedAt(null);
1071
        $roleDao->save($role);
1072
        $this->assertNull($role->getCreatedAt());
1073
    }
1074
1075
    /**
1076
     * @depends testDaoGeneration
1077
     */
1078
    public function testFindFromSql()
1079
    {
1080
        $roleDao = new TestRoleDao($this->tdbmService);
1081
1082
        $roles = $roleDao->getRolesByRightCanSing();
1083
        $this->assertCount(2, $roles);
1084
        $this->assertInstanceOf(RoleBean::class, $roles[0]);
1085
    }
1086
1087
    /**
1088
     * @depends testDaoGeneration
1089
     */
1090
    public function testFindOneFromSql()
1091
    {
1092
        $roleDao = new TestRoleDao($this->tdbmService);
1093
1094
        $role = $roleDao->getRoleByRightCanSingAndNameSinger();
1095
        $this->assertInstanceOf(RoleBean::class, $role);
1096
    }
1097
1098
    /**
1099
     * @depends testDaoGeneration
1100
     */
1101
    public function testCreateEmptyExtendedBean()
1102
    {
1103
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92
1104
1105
        $dogDao = new DogDao($this->tdbmService);
1106
1107
        // We are not filling no field that is part of dog table.
1108
        $dog = new DogBean('Youki');
1109
        $dog->setOrder(1);
1110
1111
        $dogDao->save($dog);
1112
    }
1113
1114
    /**
1115
     * @depends testCreateEmptyExtendedBean
1116
     */
1117
    public function testFetchEmptyExtendedBean()
1118
    {
1119
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92
1120
1121
        $animalDao = new AnimalDao($this->tdbmService);
1122
1123
        // We are not filling no field that is part of dog table.
1124
        $animalBean = $animalDao->getById(1);
1125
1126
        $this->assertInstanceOf(DogBean::class, $animalBean);
1127
    }
1128
1129
    /**
1130
     * @depends testDaoGeneration
1131
     */
1132
    public function testTwoBranchesHierarchy()
1133
    {
1134
        // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131
1135
1136
        $catDao = new CatDao($this->tdbmService);
1137
1138
        // We are not filling no field that is part of dog table.
1139
        $cat = new CatBean('Mew');
1140
        $cat->setOrder(2);
1141
1142
        $catDao->save($cat);
1143
    }
1144
1145
    /**
1146
     * @depends testTwoBranchesHierarchy
1147
     */
1148
    public function testFetchTwoBranchesHierarchy()
1149
    {
1150
        // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131
1151
1152
        $animalDao = new AnimalDao($this->tdbmService);
1153
1154
        $animalBean = $animalDao->getById(2);
1155
1156
        $this->assertInstanceOf(CatBean::class, $animalBean);
1157
        /* @var $animalBean CatBean */
1158
        $animalBean->setCutenessLevel(999);
1159
1160
        $animalDao->save($animalBean);
1161
    }
1162
1163
    /**
1164
     * @depends testDaoGeneration
1165
     */
1166
    public function testExceptionOnGetById()
1167
    {
1168
        $countryDao = new CountryDao($this->tdbmService);
1169
        $this->expectException(\TypeError::class);
1170
        $countryDao->getById(null);
1171
    }
1172
1173
    /**
1174
     * @depends testDaoGeneration
1175
     */
1176
    public function testDisconnectedManyToOne()
1177
    {
1178
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/99
1179
1180
        $country = new CountryBean('Spain');
1181
1182
        $user = new UserBean('John Doe', '[email protected]', $country, 'john.doe');
1183
1184
        $this->assertCount(1, $country->getUsers());
1185
        $this->assertSame($user, $country->getUsers()[0]);
1186
    }
1187
1188
    /**
1189
     * @depends testDaoGeneration
1190
     */
1191 View Code Duplication
    public function testOrderByExternalCol()
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...
1192
    {
1193
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/106
1194
1195
        $userDao = new TestUserDao($this->tdbmService);
1196
        $users = $userDao->getUsersByCountryName();
1197
1198
        $this->assertEquals('UK', $users[0]->getCountry()->getLabel());
1199
    }
1200
1201
    /**
1202
     * @depends testDaoGeneration
1203
     */
1204
    public function testResultIteratorSort()
1205
    {
1206
        $userDao = new UserDao($this->tdbmService);
1207
        $users = $userDao->findAll()->withOrder('country.label DESC');
1208
1209
        $this->assertEquals('UK', $users[0]->getCountry()->getLabel());
1210
1211
        $users = $users->withOrder('country.label ASC');
1212
        $this->assertEquals('France', $users[0]->getCountry()->getLabel());
1213
    }
1214
1215
    /**
1216
     * @depends testDaoGeneration
1217
     */
1218
    public function testResultIteratorWithParameters()
1219
    {
1220
        $userDao = new TestUserDao($this->tdbmService);
1221
        $users = $userDao->getUsersByLoginStartingWith()->withParameters(['login' => 'bill%']);
1222
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
1223
1224
        $users = $users->withParameters(['login' => 'jean%']);
1225
        $this->assertEquals('jean.dupont', $users[0]->getLogin());
1226
    }
1227
1228
    /**
1229
     * @depends testDaoGeneration
1230
     */
1231 View Code Duplication
    public function testOrderByExpression()
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...
1232
    {
1233
        $userDao = new TestUserDao($this->tdbmService);
1234
        $users = $userDao->getUsersByReversedCountryName();
1235
1236
        $this->assertEquals('Jamaica', $users[0]->getCountry()->getLabel());
1237
    }
1238
1239
    /**
1240
     * @depends testDaoGeneration
1241
     */
1242
    public function testOrderByException()
1243
    {
1244
        $userDao = new TestUserDao($this->tdbmService);
1245
        $users = $userDao->getUsersByInvalidOrderBy();
1246
        $this->expectException(TDBMInvalidArgumentException::class);
1247
        $user = $users[0];
0 ignored issues
show
Unused Code introduced by
$user 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...
1248
    }
1249
1250
    /**
1251
     * @depends testDaoGeneration
1252
     */
1253
    public function testOrderByProtectedColumn()
1254
    {
1255
        $animalDao = new AnimalDao($this->tdbmService);
1256
        $animals = $animalDao->findAll();
1257
        $animals = $animals->withOrder('`order` ASC');
1258
1259
        $this->assertInstanceOf(DogBean::class, $animals[0]);
1260
        $this->assertInstanceOf(CatBean::class, $animals[1]);
1261
1262
        $animals = $animals->withOrder('`order` DESC');
1263
1264
        $this->assertInstanceOf(CatBean::class, $animals[0]);
1265
        $this->assertInstanceOf(DogBean::class, $animals[1]);
1266
    }
1267
1268
    /**
1269
     * @depends testDaoGeneration
1270
     */
1271
    public function testGetOnAllNullableValues()
1272
    {
1273
        // Tests that a get performed on a column that has only nullable fields succeeds.
1274
        $allNullable = new AllNullableBean();
1275
        $this->assertNull($allNullable->getId());
1276
        $this->assertNull($allNullable->getLabel());
1277
        $this->assertNull($allNullable->getCountry());
1278
    }
1279
1280
    /**
1281
     * @depends testDaoGeneration
1282
     */
1283
    public function testExceptionOnMultipleInheritance()
1284
    {
1285
        $connection = self::getConnection();
1286
        self::insert($connection, 'animal', [
1287
            'id' => 99, 'name' => 'Snoofield',
1288
        ]);
1289
        self::insert($connection, 'dog', [
1290
            'id' => 99, 'race' => 'dog',
1291
        ]);
1292
        self::insert($connection, 'cat', [
1293
            'id' => 99, 'cuteness_level' => 0,
1294
        ]);
1295
1296
        $catched = false;
1297
        try {
1298
            $animalDao = new AnimalDao($this->tdbmService);
1299
            $animalDao->getById(99);
1300
        } catch (TDBMInheritanceException $e) {
1301
            $catched = true;
1302
        }
1303
        $this->assertTrue($catched, 'Exception TDBMInheritanceException was not caught');
1304
1305
        self::delete($connection, 'cat', ['id' => 99]);
1306
        self::delete($connection, 'dog', ['id' => 99]);
1307
        self::delete($connection, 'animal', ['id' => 99]);
1308
    }
1309
1310
    /**
1311
     * @depends testDaoGeneration
1312
     */
1313
    public function testReferenceNotSaved()
1314
    {
1315
        $boatDao = new BoatDao($this->tdbmService);
1316
1317
        $country = new CountryBean('Atlantis');
1318
        $boat = new BoatBean($country, 'Titanic');
1319
1320
        $boatDao->save($boat);
1321
    }
1322
1323
    /**
1324
     * @depends testDaoGeneration
1325
     */
1326
    public function testReferenceDeleted()
1327
    {
1328
        $countryDao = new CountryDao($this->tdbmService);
1329
        $boatDao = new BoatDao($this->tdbmService);
1330
1331
        $country = new CountryBean('Atlantis');
1332
        $countryDao->save($country);
1333
1334
        $boat = new BoatBean($country, 'Titanic');
1335
        $countryDao->delete($country);
1336
1337
        $this->expectException(TDBMMissingReferenceException::class);
1338
        $boatDao->save($boat);
1339
    }
1340
1341
    /**
1342
     * @depends testDaoGeneration
1343
     */
1344 View Code Duplication
    public function testCyclicReferenceWithInheritance()
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...
1345
    {
1346
        $userDao = new UserDao($this->tdbmService);
1347
1348
        $country = new CountryBean('Norrisland');
1349
        $user = new UserBean('Chuck Norris', '[email protected]', $country, 'chuck.norris');
1350
1351
        $user->setManager($user);
1352
1353
        $this->expectException(TDBMCyclicReferenceException::class);
1354
        $userDao->save($user);
1355
    }
1356
1357
    /**
1358
     * @depends testDaoGeneration
1359
     */
1360
    public function testCyclicReference()
1361
    {
1362
        $categoryDao = new CategoryDao($this->tdbmService);
1363
1364
        $category = new CategoryBean('Root');
1365
1366
        $category->setParent($category);
1367
1368
        $this->expectException(TDBMCyclicReferenceException::class);
1369
        $categoryDao->save($category);
1370
    }
1371
1372
    /**
1373
     * @depends testDaoGeneration
1374
     */
1375
    public function testCorrectTypeForPrimaryKeyAfterSave()
1376
    {
1377
        // PosqtgreSQL does not particularly like empty inserts (i.e.: "INSERT INTO all_nullable () VALUES ()" )
1378
        $this->onlyMySql();
1379
1380
        $allNullableDao = new AllNullableDao($this->tdbmService);
1381
        $allNullable = new AllNullableBean();
1382
        $allNullableDao->save($allNullable);
1383
        $id = $allNullable->getId();
1384
1385
        $this->assertTrue(is_int($id));
1386
    }
1387
1388
    /**
1389
     * @depends testDaoGeneration
1390
     */
1391
    public function testPSR2Compliance()
1392
    {
1393
        $process = new Process('vendor/bin/php-cs-fixer fix src/Test/  --dry-run --diff --rules=@PSR2');
1394
        $process->run();
1395
1396
        // executes after the command finishes
1397
        if (!$process->isSuccessful()) {
1398
            echo $process->getOutput();
1399
            $this->fail('Generated code is not PRS2 compliant');
1400
        }
1401
    }
1402
1403
    /**
1404
     * @depends testDaoGeneration
1405
     */
1406
    public function testFindOneByGeneration()
1407
    {
1408
        $reflectionMethod = new \ReflectionMethod(UserBaseDao::class, 'findOneByLogin');
1409
        $parameters = $reflectionMethod->getParameters();
1410
1411
        $this->assertCount(2, $parameters);
1412
        $this->assertSame('login', $parameters[0]->getName());
0 ignored issues
show
Bug introduced by
Consider using $parameters[0]->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
1413
        $this->assertSame('additionalTablesFetch', $parameters[1]->getName());
0 ignored issues
show
Bug introduced by
Consider using $parameters[1]->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
1414
    }
1415
1416
    /**
1417
     * @depends testDaoGeneration
1418
     */
1419 View Code Duplication
    public function testUuid()
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...
1420
    {
1421
        $article = new ArticleBean('content');
1422
        $this->assertSame('content', $article->getContent());
1423
        $this->assertNotEmpty($article->getId());
1424
        $uuid = Uuid::fromString($article->getId());
1425
        $this->assertSame(1, $uuid->getVersion());
1426
    }
1427
1428
    /**
1429
     * @depends testDaoGeneration
1430
     */
1431 View Code Duplication
    public function testUuidv4()
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...
1432
    {
1433
        $article = new Article2Bean('content');
1434
        $this->assertSame('content', $article->getContent());
1435
        $this->assertNotEmpty($article->getId());
1436
        $uuid = Uuid::fromString($article->getId());
1437
        $this->assertSame(4, $uuid->getVersion());
1438
    }
1439
1440
    /**
1441
     * @depends testDaoGeneration
1442
     */
1443
    public function testTypeHintedConstructors()
1444
    {
1445
        $userBaseBeanReflectionConstructor = new \ReflectionMethod(UserBaseBean::class, '__construct');
1446
        $nameParam = $userBaseBeanReflectionConstructor->getParameters()[0];
1447
1448
        $this->assertSame('string', (string) $nameParam->getType());
1449
    }
1450
1451
    /**
1452
     * @depends testDaoGeneration
1453
     */
1454
    public function testSaveTransaction()
1455
    {
1456
        $countryDao = new CountryDao($this->tdbmService);
1457
1458
        $boatDao = new BoatDao($this->tdbmService);
1459
        $boatBean = $boatDao->getById(1);
1460
        $boatBean->setName('Bismark');
1461
1462
        $boatBean->getCountry();
1463
1464
        // Let's insert a row without telling TDBM to trigger an error!
1465
        self::insert($this->getConnection(), 'sailed_countries', [
1466
            'boat_id' => 1,
1467
            'country_id' => 2
1468
        ]);
1469
1470
        $boatBean->addCountry($countryDao->getById(2));
1471
1472
        $this->expectException(UniqueConstraintViolationException::class);
1473
1474
        $boatDao->save($boatBean);
1475
    }
1476
1477
    /**
1478
     * @depends testSaveTransaction
1479
     */
1480
    public function testSaveTransaction2()
1481
    {
1482
        $boatDao = new BoatDao($this->tdbmService);
1483
        $boatBean = $boatDao->getById(1);
1484
1485
        // The name should not have been saved because the transaction of the previous test should have rollbacked.
1486
        $this->assertNotSame('Bismark', $boatBean->getName());
1487
    }
1488
1489
    /**
1490
     * @depends testDaoGeneration
1491
     */
1492
    public function testForeignKeyPointingToNonPrimaryKey()
1493
    {
1494
        $dao = new RefNoPrimKeyDao($this->tdbmService);
1495
        $bean = $dao->getById(1);
1496
1497
        $this->assertSame('foo', $bean->getFrom()->getTo());
1498
    }
1499
}
1500