Completed
Push — master ( ef5aef...dc6a81 )
by David
13s
created

TDBMDaoGeneratorTest::testFindOneFromSql()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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