Completed
Pull Request — master (#5669)
by Jeremy
08:29
created

testMatchingWithComparisons()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 43
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 43
rs 8.8571
cc 1
eloc 30
nc 1
nop 4
1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional;
4
5
use Doctrine\Common\Collections\Criteria;
6
use Doctrine\ORM\UnitOfWork;
7
use Doctrine\Tests\Models\CMS\CmsTag;
8
use Doctrine\Tests\Models\CMS\CmsUser,
9
    Doctrine\Tests\Models\CMS\CmsGroup,
10
    Doctrine\Common\Collections\ArrayCollection;
11
use Doctrine\Tests\OrmFunctionalTestCase;
12
13
/**
14
 * Basic many-to-many association tests.
15
 * ("Working with associations")
16
 *
17
 * @author robo
18
 */
19
class ManyToManyBasicAssociationTest extends OrmFunctionalTestCase
20
{
21
    protected function setUp()
22
    {
23
        $this->useModelSet('cms');
24
        parent::setUp();
25
    }
26
27
    public function testUnsetManyToMany()
28
    {
29
        $user = $this->addCmsUserGblancoWithGroups(1);
30
31
        unset($user->groups[0]->users[0]); // inverse side
32
        unset($user->groups[0]); // owning side!
33
34
        $this->_em->flush();
35
36
        // Check that the link in the association table has been deleted
37
        $this->assertGblancoGroupCountIs(0);
38
    }
39
40
    public function testBasicManyToManyJoin()
41
    {
42
        $user = $this->addCmsUserGblancoWithGroups(1);
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...
43
        $this->_em->clear();
44
45
        $this->assertEquals(0, $this->_em->getUnitOfWork()->size());
46
47
        $query = $this->_em->createQuery("select u, g from Doctrine\Tests\Models\CMS\CmsUser u join u.groups g");
48
49
        $result = $query->getResult();
50
51
        $this->assertEquals(2, $this->_em->getUnitOfWork()->size());
52
        $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $result[0]);
53
        $this->assertEquals('Guilherme', $result[0]->name);
54
        $this->assertEquals(1, $result[0]->getGroups()->count());
55
        $groups = $result[0]->getGroups();
56
        $this->assertEquals('Developers_0', $groups[0]->getName());
57
58
        $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($result[0]));
59
        $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($groups[0]));
60
61
        $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $groups);
62
        $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $groups[0]->getUsers());
63
64
        $groups[0]->getUsers()->clear();
65
        $groups->clear();
66
67
        $this->_em->flush();
68
        $this->_em->clear();
69
70
        $query = $this->_em->createQuery("select u, g from Doctrine\Tests\Models\CMS\CmsUser u join u.groups g");
71
        $this->assertEquals(0, count($query->getResult()));
72
    }
73
74
    public function testManyToManyAddRemove()
75
    {
76
        $user = $this->addCmsUserGblancoWithGroups(2);
77
        $this->_em->clear();
78
79
        $uRep = $this->_em->getRepository(get_class($user));
80
81
        // Get user
82
        $user = $uRep->findOneById($user->getId());
0 ignored issues
show
Documentation Bug introduced by
The method findOneById does not exist on object<Doctrine\ORM\EntityRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
83
84
        $this->assertNotNull($user, "Has to return exactly one entry.");
85
86
        $this->assertFalse($user->getGroups()->isInitialized());
87
88
        // Check groups
89
        $this->assertEquals(2, $user->getGroups()->count());
90
91
        $this->assertTrue($user->getGroups()->isInitialized());
92
93
        // Remove first group
94
        unset($user->groups[0]);
95
        //$user->getGroups()->remove(0);
96
97
        $this->_em->flush();
98
        $this->_em->clear();
99
100
        // Reload same user
101
        $user2 = $uRep->findOneById($user->getId());
0 ignored issues
show
Documentation Bug introduced by
The method findOneById does not exist on object<Doctrine\ORM\EntityRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
102
103
        // Check groups
104
        $this->assertEquals(1, $user2->getGroups()->count());
105
    }
106
107
    public function testManyToManyInverseSideIgnored()
108
    {
109
        $user = $this->addCmsUserGblancoWithGroups(0);
110
111
        $group = new CmsGroup;
112
        $group->name = 'Humans';
113
114
        // modify directly, addUser() would also (properly) set the owning side
115
        $group->users[] = $user;
116
117
        $this->_em->persist($user);
118
        $this->_em->persist($group);
119
        $this->_em->flush();
120
        $this->_em->clear();
121
122
        // Association should not exist
123
        $user2 = $this->_em->find(get_class($user), $user->getId());
124
125
        $this->assertNotNull($user2, "Has to return exactly one entry.");
126
        $this->assertEquals(0, $user2->getGroups()->count());
127
    }
128
129
    public function testManyToManyCollectionClearing()
130
    {
131
        $user = $this->addCmsUserGblancoWithGroups($groupCount = 10);
132
133
        // Check that there are indeed 10 links in the association table
134
        $this->assertGblancoGroupCountIs($groupCount);
135
136
        $user->groups->clear();
137
138
        $this->_em->flush();
139
140
        // Check that the links in the association table have been deleted
141
        $this->assertGblancoGroupCountIs(0);
142
    }
143
144
    public function testManyToManyCollectionClearAndAdd()
145
    {
146
        $user = $this->addCmsUserGblancoWithGroups($groupCount = 10);
147
148
        $groups = $user->groups->toArray();
149
        $user->groups->clear();
150
151
        foreach ($groups AS $group) {
152
            $user->groups[] = $group;
153
        }
154
155
        $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $user->groups);
156
        $this->assertTrue($user->groups->isDirty());
157
158
        $this->assertEquals($groupCount, count($user->groups), "There should be 10 groups in the collection.");
159
160
        $this->_em->flush();
161
162
        $this->assertGblancoGroupCountIs($groupCount);
163
    }
164
165
    /**
166
     * @param int $expectedGroupCount
167
     */
168
    public function assertGblancoGroupCountIs($expectedGroupCount)
169
    {
170
        $countDql = "SELECT count(g.id) FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g WHERE u.username = 'gblanco'";
171
        $this->assertEquals(
172
            $expectedGroupCount,
173
            $this->_em->createQuery($countDql)->getSingleScalarResult(),
174
            "Failed to verify that CmsUser with username 'gblanco' has a group count of 10 with a DQL count query."
175
        );
176
    }
177
178
    public function testRetrieveManyToManyAndAddMore()
179
    {
180
        $user = $this->addCmsUserGblancoWithGroups(2);
181
182
        $group = new CmsGroup();
183
        $group->name = 'Developers_Fresh';
184
        $this->_em->persist($group);
185
        $this->_em->flush();
186
187
        $this->_em->clear();
188
189
        /* @var $freshUser CmsUser */
190
        $freshUser = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $user->getId());
191
        $newGroup = new CmsGroup();
192
        $newGroup->setName('12Monkeys');
193
        $freshUser->addGroup($newGroup);
194
195
        $this->assertFalse($freshUser->groups->isInitialized(), "CmsUser::groups Collection has to be uninitialized for this test.");
0 ignored issues
show
Bug introduced by
The method isInitialized() does not seem to exist on object<Doctrine\Common\C...ctions\ArrayCollection>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
196
197
        $this->_em->flush();
198
199
        $this->assertFalse($freshUser->groups->isInitialized(), "CmsUser::groups Collection has to be uninitialized for this test.");
0 ignored issues
show
Bug introduced by
The method isInitialized() does not seem to exist on object<Doctrine\Common\C...ctions\ArrayCollection>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
200
        $this->assertEquals(3, count($freshUser->getGroups()));
201
        $this->assertEquals(3, count($freshUser->getGroups()->getSnapshot()), "Snapshot of CmsUser::groups should contain 3 entries.");
0 ignored issues
show
Bug introduced by
The method getSnapshot() does not seem to exist on object<Doctrine\Common\C...ctions\ArrayCollection>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
202
203
        $this->_em->clear();
204
205
        $freshUser = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $user->getId());
206
        $this->assertEquals(3, count($freshUser->getGroups()));
207
    }
208
209
    /**
210
     * @group DDC-130
211
     */
212
    public function testRemoveUserWithManyGroups()
213
    {
214
        $user = $this->addCmsUserGblancoWithGroups(2);
215
        $userId = $user->getId();
216
217
        $this->_em->remove($user);
218
        $this->_em->flush();
219
220
        $newUser = $this->_em->find(get_class($user), $userId);
221
        $this->assertNull($newUser);
222
    }
223
224
    /**
225
     * @group DDC-130
226
     */
227
    public function testRemoveGroupWithUser()
228
    {
229
        $user = $this->addCmsUserGblancoWithGroups(2);
230
231
        foreach ($user->getGroups() AS $group) {
0 ignored issues
show
Bug introduced by
The expression $user->getGroups() of type object<Doctrine\Common\C...yCollection>|array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
232
            $this->_em->remove($group);
233
        }
234
        $this->_em->flush();
235
        $this->_em->clear();
236
237
        $newUser = $this->_em->find(get_class($user), $user->getId());
238
        $this->assertEquals(0, count($newUser->getGroups()));
239
    }
240
241
    public function testDereferenceCollectionDelete()
242
    {
243
        $user = $this->addCmsUserGblancoWithGroups(2);
244
        $user->groups = null;
245
246
        $this->_em->flush();
247
        $this->_em->clear();
248
249
        $newUser = $this->_em->find(get_class($user), $user->getId());
250
        $this->assertEquals(0, count($newUser->getGroups()));
251
    }
252
253
    /**
254
     * @group DDC-839
255
     */
256
    public function testWorkWithDqlHydratedEmptyCollection()
257
    {
258
        $user = $this->addCmsUserGblancoWithGroups(0);
259
        $group = new CmsGroup();
260
        $group->name = "Developers0";
261
        $this->_em->persist($group);
262
263
        $this->_em->flush();
264
        $this->_em->clear();
265
266
        $newUser = $this->_em->createQuery('SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.groups g WHERE u.id = ?1')
267
                             ->setParameter(1, $user->getId())
268
                             ->getSingleResult();
269
        $this->assertEquals(0, count($newUser->groups));
270
        $this->assertInternalType('array', $newUser->groups->getMapping());
271
272
        $newUser->addGroup($group);
273
274
        $this->_em->flush();
275
        $this->_em->clear();
276
277
        $newUser = $this->_em->find(get_class($user), $user->getId());
278
        $this->assertEquals(1, count($newUser->groups));
279
    }
280
281
    /**
282
     * @param  int $groupCount
283
     * @return CmsUser
284
     */
285
    public function addCmsUserGblancoWithGroups($groupCount = 1)
286
    {
287
        $user = new CmsUser;
288
        $user->name = 'Guilherme';
289
        $user->username = 'gblanco';
290
        $user->status = 'developer';
291
292
        for ($i=0; $i < $groupCount; ++$i) {
293
            $group = new CmsGroup;
294
            $group->name = 'Developers_' . $i;
295
            $user->addGroup($group);
296
        }
297
298
        $this->_em->persist($user);
299
        $this->_em->flush();
300
301
        $this->assertNotNull($user->getId(), "User 'gblanco' should have an ID assigned after the persist()/flush() operation.");
302
303
        return $user;
304
    }
305
306
    /**
307
     * @group DDC-980
308
     */
309
    public function testUpdateDeleteSizeSubselectQueries()
310
    {
311
        $this->_em->createQuery("DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) = 10")->execute();
312
        $this->_em->createQuery("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.status = 'inactive' WHERE SIZE(u.groups) = 10")->execute();
313
    }
314
315
    /**
316
     * @group DDC-978
317
     */
318
    public function testClearAndResetCollection()
319
    {
320
        $user = $this->addCmsUserGblancoWithGroups(2);
321
        $group1 = new CmsGroup;
322
        $group1->name = 'Developers_New1';
323
        $group2 = new CmsGroup;
324
        $group2->name = 'Developers_New2';
325
326
        $this->_em->persist($group1);
327
        $this->_em->persist($group2);
328
        $this->_em->flush();
329
        $this->_em->clear();
330
331
        $user = $this->_em->find(get_class($user), $user->id);
332
333
        $coll = new ArrayCollection(array($group1, $group2));
334
        $user->groups = $coll;
335
        $this->_em->flush();
336
        $this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $user->groups,
337
            "UnitOfWork should have replaced ArrayCollection with PersistentCollection.");
338
        $this->_em->flush();
339
340
        $this->_em->clear();
341
342
        $user = $this->_em->find(get_class($user), $user->id);
343
        $this->assertEquals(2, count($user->groups));
344
        $this->assertEquals('Developers_New1', $user->groups[0]->name);
345
        $this->assertEquals('Developers_New2', $user->groups[1]->name);
346
    }
347
348
    /**
349
     * @group DDC-733
350
     */
351
    public function testInitializePersistentCollection()
352
    {
353
        $user = $this->addCmsUserGblancoWithGroups(2);
354
        $this->_em->clear();
355
356
        $user = $this->_em->find(get_class($user), $user->id);
357
358
        $this->assertFalse($user->groups->isInitialized(), "Pre-condition: lazy collection");
359
        $this->_em->getUnitOfWork()->initializeObject($user->groups);
360
        $this->assertTrue($user->groups->isInitialized(), "Collection should be initialized after calling UnitOfWork::initializeObject()");
361
    }
362
363
    /**
364
     * @group DDC-1189
365
     * @group DDC-956
366
     */
367
    public function testClearBeforeLazyLoad()
368
    {
369
        $user = $this->addCmsUserGblancoWithGroups(4);
370
371
        $this->_em->clear();
372
373
        $user = $this->_em->find(get_class($user), $user->id);
374
        $user->groups->clear();
375
        $this->assertEquals(0, count($user->groups));
376
377
        $this->_em->flush();
378
379
        $user = $this->_em->find(get_class($user), $user->id);
380
        $this->assertEquals(0, count($user->groups));
381
    }
382
383
    /**
384
     * @group DDC-3952
385
     */
386
    public function testManyToManyOrderByIsNotIgnored()
387
    {
388
        $user = $this->addCmsUserGblancoWithGroups(1);
389
390
        $group1 = new CmsGroup;
391
        $group2 = new CmsGroup;
392
        $group3 = new CmsGroup;
393
394
        $group1->name = 'C';
395
        $group2->name = 'A';
396
        $group3->name = 'B';
397
398
        $user->addGroup($group1);
399
        $user->addGroup($group2);
400
        $user->addGroup($group3);
401
402
        $this->_em->persist($user);
403
        $this->_em->flush();
404
405
        $this->_em->clear();
406
407
        $user = $this->_em->find(get_class($user), $user->id);
408
409
        $criteria = Criteria::create()
410
            ->orderBy(['name' => Criteria::ASC]);
411
412
        $this->assertEquals(
413
            ['A', 'B', 'C', 'Developers_0'],
414
            $user
415
                ->getGroups()
416
                ->matching($criteria)
417
                ->map(function (CmsGroup $group) {
418
                    return $group->getName();
419
                })
420
                ->toArray()
421
        );
422
    }
423
424
    /**
425
     * @group DDC-3952
426
     */
427
    public function testManyToManyOrderByHonorsFieldNameColumnNameAliases()
428
    {
429
        $user = new CmsUser;
430
        $user->name = 'Guilherme';
431
        $user->username = 'gblanco';
432
        $user->status = 'developer';
433
434
        $tag1 = new CmsTag;
435
        $tag2 = new CmsTag;
436
        $tag3 = new CmsTag;
437
438
        $tag1->name = 'C';
439
        $tag2->name = 'A';
440
        $tag3->name = 'B';
441
442
        $user->addTag($tag1);
443
        $user->addTag($tag2);
444
        $user->addTag($tag3);
445
446
        $this->_em->persist($user);
447
        $this->_em->flush();
448
449
        $this->_em->clear();
450
451
        $user = $this->_em->find(get_class($user), $user->id);
452
453
        $criteria = Criteria::create()
454
            ->orderBy(['name' => Criteria::ASC]);
455
456
        $this->assertEquals(
457
            ['A', 'B', 'C'],
458
            $user
459
                ->getTags()
460
                ->matching($criteria)
461
                ->map(function (CmsTag $tag) {
462
                    return $tag->getName();
463
                })
464
                ->toArray()
465
        );
466
    }
467
468
    public function testMatchingWithLimit()
469
    {
470
        $user = $this->addCmsUserGblancoWithGroups(2);
471
        $this->_em->clear();
472
473
        $user = $this->_em->find(get_class($user), $user->id);
474
475
        $groups = $user->groups;
476
        $this->assertFalse($user->groups->isInitialized(), "Pre-condition: lazy collection");
477
478
        $criteria = Criteria::create()->setMaxResults(1);
479
        $result   = $groups->matching($criteria);
480
481
        $this->assertCount(1, $result);
482
483
        $this->assertFalse($user->groups->isInitialized(), "Post-condition: matching does not initialize collection");
484
    }
485
486
    public function testMatchingWithOffset()
487
    {
488
        $user = $this->addCmsUserGblancoWithGroups(2);
489
        $this->_em->clear();
490
491
        $user = $this->_em->find(get_class($user), $user->id);
492
493
        $groups = $user->groups;
494
        $this->assertFalse($user->groups->isInitialized(), "Pre-condition: lazy collection");
495
496
        $criteria = Criteria::create()->setFirstResult(1);
497
        $result   = $groups->matching($criteria);
498
499
        $this->assertCount(1, $result);
500
501
        $firstGroup = $result->first();
502
        $this->assertEquals('Developers_1', $firstGroup->name);
503
504
        $this->assertFalse($user->groups->isInitialized(), "Post-condition: matching does not initialize collection");
505
    }
506
507
    public function testMatchingWithLimitAndOffset()
508
    {
509
        $user = $this->addCmsUserGblancoWithGroups(5);
510
        $this->_em->clear();
511
512
        $user = $this->_em->find(get_class($user), $user->id);
513
514
        $groups = $user->groups;
515
        $this->assertFalse($user->groups->isInitialized(), "Pre-condition: lazy collection");
516
517
        $criteria = Criteria::create()->setFirstResult(1)->setMaxResults(3);
518
        $result   = $groups->matching($criteria);
519
520
        $this->assertCount(3, $result);
521
522
        $firstGroup = $result->first();
523
        $this->assertEquals('Developers_1', $firstGroup->name);
524
525
        $lastGroup = $result->last();
526
        $this->assertEquals('Developers_3', $lastGroup->name);
527
528
        $this->assertFalse($user->groups->isInitialized(), "Post-condition: matching does not initialize collection");
529
    }
530
531
    public function testMatching()
532
    {
533
        $user = $this->addCmsUserGblancoWithGroups(2);
534
        $this->_em->clear();
535
536
        $user = $this->_em->find(get_class($user), $user->id);
537
538
        $groups = $user->groups;
539
        $this->assertFalse($user->groups->isInitialized(), "Pre-condition: lazy collection");
540
541
        $criteria = Criteria::create()->where(Criteria::expr()->eq('name', (string) 'Developers_0'));
542
        $result   = $groups->matching($criteria);
543
544
        $this->assertCount(1, $result);
545
546
        $firstGroup = $result->first();
547
        $this->assertEquals('Developers_0', $firstGroup->name);
548
549
        $this->assertFalse($user->groups->isInitialized(), "Post-condition: matching does not initialize collection");
550
    }
551
552
    /**
553
     * @group DDC-3890
554
     * @dataProvider matchingWithComparisonsProvider
555
     * @param string $method
556
     * @param string $field
557
     * @param mixed|mixed[] $value
558
     * @param array $expectedTagNames
559
     */
560
    public function testMatchingWithComparisons($method, $field, $value, array $expectedTagNames)
561
    {
562
        $user = new CmsUser;
563
        $user->name = 'Guilherme';
564
        $user->username = 'gblanco';
565
        $user->status = 'developer';
566
567
        $tag1 = new CmsTag;
568
        $tag2 = new CmsTag;
569
        $tag3 = new CmsTag;
570
571
        $tag1->name = 'A';
572
        $tag2->name = 'B';
573
        $tag3->name = 'C';
574
575
        $user->addTag($tag1);
576
        $user->addTag($tag2);
577
        $user->addTag($tag3);
578
579
        $this->_em->persist($user);
580
        $this->_em->flush();
581
582
        $this->_em->clear();
583
584
        $user = $this->_em->find(get_class($user), $user->id);
585
586
        $criteria = Criteria::create();
587
588
        $expr = Criteria::expr();
589
        $condition = call_user_func([$expr, $method], $field, $value);
590
        $criteria->where($condition);
591
592
        $this->assertEquals(
593
            $expectedTagNames,
594
            $user
595
                ->getTags()
596
                ->matching($criteria)
597
                ->map(function (CmsTag $tag) {
598
                    return $tag->getName();
599
                })
600
                ->toArray()
601
        );
602
    }
603
604
    public function matchingWithComparisonsProvider()
605
    {
606
        return [
607
            'lt' => [
608
                'lt', 'name', 'B', ['A']
609
            ],
610
            'lte' => [
611
                'lte', 'name', 'B', ['A', 'B']
612
            ],
613
            'eq' => [
614
                'eq', 'name', 'B', ['B']
615
            ],
616
            'neq' => [
617
                'neq', 'name', 'B', ['A', 'C']
618
            ],
619
            'gt' => [
620
                'gt', 'name', 'B', ['C']
621
            ],
622
            'gte' => [
623
                'gte', 'name', 'B', ['B', 'C']
624
            ],
625
            'in' => [
626
                'in', 'name', ['A', 'C'], ['A', 'C']
627
            ],
628
            'notIn' => [
629
                'notIn', 'name', ['A', 'C'], ['B']
630
            ],
631
            'contains' => [
632
                'contains', 'name', 'B', ['B']
633
            ],
634
        ];
635
    }
636
637
    /**
638
     * @group DDC-3890
639
     */
640
    public function testMatchingWithIsNull()
641
    {
642
        $user = new CmsUser;
643
        $user->name = 'Guilherme';
644
        $user->username = 'gblanco';
645
        $user->status = 'developer';
646
647
        $tag1 = new CmsTag;
648
        $tag2 = new CmsTag;
649
        $tag3 = new CmsTag;
650
651
        $tag1->name = null;
652
        $tag2->name = 'B';
653
        $tag3->name = 'C';
654
655
        $user->addTag($tag1);
656
        $user->addTag($tag2);
657
        $user->addTag($tag3);
658
659
        $this->_em->persist($user);
660
        $this->_em->flush();
661
662
        $this->_em->clear();
663
664
        $user = $this->_em->find(get_class($user), $user->id);
665
666
        $criteria = Criteria::create();
667
668
        $criteria->where(Criteria::expr()->isNull('name'));
669
670
        $this->assertEquals(
671
            [null],
672
            $user
673
                ->getTags()
674
                ->matching($criteria)
675
                ->map(function (CmsTag $tag) {
676
                    return $tag->getName();
677
                })
678
                ->toArray()
679
        );
680
    }
681
}
682