1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
/** |
5
|
|
|
* This file is part of the Happyr Doctrine Specification package. |
6
|
|
|
* |
7
|
|
|
* (c) Tobias Nyholm <[email protected]> |
8
|
|
|
* Kacper Gunia <[email protected]> |
9
|
|
|
* Peter Gribanov <[email protected]> |
10
|
|
|
* |
11
|
|
|
* For the full copyright and license information, please view the LICENSE |
12
|
|
|
* file that was distributed with this source code. |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace tests\Happyr\DoctrineSpecification\Filter; |
16
|
|
|
|
17
|
|
|
use Doctrine\ORM\QueryBuilder; |
18
|
|
|
use Happyr\DoctrineSpecification\Filter\Filter; |
19
|
|
|
use Happyr\DoctrineSpecification\Filter\IsEmpty; |
20
|
|
|
use Happyr\DoctrineSpecification\Filter\Satisfiable; |
21
|
|
|
use PhpSpec\ObjectBehavior; |
22
|
|
|
use tests\Happyr\DoctrineSpecification\Game; |
23
|
|
|
use tests\Happyr\DoctrineSpecification\Player; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @mixin IsEmpty |
27
|
|
|
*/ |
28
|
|
|
final class IsEmptySpec extends ObjectBehavior |
29
|
|
|
{ |
30
|
|
|
private $field = 'foobar'; |
31
|
|
|
|
32
|
|
|
public function let(): void |
33
|
|
|
{ |
34
|
|
|
$this->beConstructedWith($this->field, null); |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
public function it_is_a_filter(): void |
38
|
|
|
{ |
39
|
|
|
$this->shouldBeAnInstanceOf(Filter::class); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function it_is_a_satisfiable(): void |
43
|
|
|
{ |
44
|
|
|
$this->shouldBeAnInstanceOf(Satisfiable::class); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
public function it_calls_empty(QueryBuilder $qb): void |
48
|
|
|
{ |
49
|
|
|
$this->getFilter($qb, 'a')->shouldReturn(sprintf('a.%s IS EMPTY', $this->field)); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
View Code Duplication |
public function it_calls_empty_in_context(QueryBuilder $qb): void |
|
|
|
|
53
|
|
|
{ |
54
|
|
|
$this->beConstructedWith($this->field, 'user'); |
55
|
|
|
|
56
|
|
|
$qb->getDQLPart('join')->willReturn([]); |
57
|
|
|
$qb->getAllAliases()->willReturn([]); |
58
|
|
|
$qb->join('root.user', 'user')->willReturn($qb); |
59
|
|
|
|
60
|
|
|
$this->getFilter($qb, 'root')->shouldReturn(sprintf('user.%s IS EMPTY', $this->field)); |
61
|
|
|
} |
62
|
|
|
|
63
|
|
View Code Duplication |
public function it_filter_array_collection(): void |
|
|
|
|
64
|
|
|
{ |
65
|
|
|
$this->beConstructedWith('points', null); |
66
|
|
|
|
67
|
|
|
$players = [ |
68
|
|
|
['pseudo' => 'Joe', 'gender' => 'M', 'points' => 2500], |
69
|
|
|
['pseudo' => 'Moe', 'gender' => 'M', 'points' => null], |
70
|
|
|
['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001], |
71
|
|
|
]; |
72
|
|
|
|
73
|
|
|
$this->filterCollection($players)->shouldYield([$players[1]]); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
View Code Duplication |
public function it_filter_object_collection(): void |
|
|
|
|
77
|
|
|
{ |
78
|
|
|
$this->beConstructedWith('points', null); |
79
|
|
|
|
80
|
|
|
$players = [ |
81
|
|
|
new Player('Joe', 'M', 2500), |
82
|
|
|
new Player('Moe', 'M', null), |
83
|
|
|
new Player('Alice', 'F', 9001), |
84
|
|
|
]; |
85
|
|
|
|
86
|
|
|
$this->filterCollection($players)->shouldYield([$players[1]]); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
View Code Duplication |
public function it_is_satisfied_with_array(): void |
|
|
|
|
90
|
|
|
{ |
91
|
|
|
$this->beConstructedWith('points', null); |
92
|
|
|
|
93
|
|
|
$playerA = ['pseudo' => 'Joe', 'gender' => 'M', 'points' => 2500]; |
94
|
|
|
$playerB = ['pseudo' => 'Moe', 'gender' => 'M', 'points' => null]; |
95
|
|
|
$playerC = ['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001]; |
96
|
|
|
|
97
|
|
|
$this->isSatisfiedBy($playerA)->shouldBe(false); |
98
|
|
|
$this->isSatisfiedBy($playerB)->shouldBe(true); |
99
|
|
|
$this->isSatisfiedBy($playerC)->shouldBe(false); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
View Code Duplication |
public function it_is_satisfied_with_object(): void |
|
|
|
|
103
|
|
|
{ |
104
|
|
|
$this->beConstructedWith('points', null); |
105
|
|
|
|
106
|
|
|
$playerA = new Player('Joe', 'M', 2500); |
107
|
|
|
$playerB = new Player('Moe', 'M', null); |
108
|
|
|
$playerC = new Player('Alice', 'F', 9001); |
109
|
|
|
|
110
|
|
|
$this->isSatisfiedBy($playerA)->shouldBe(false); |
111
|
|
|
$this->isSatisfiedBy($playerB)->shouldBe(true); |
112
|
|
|
$this->isSatisfiedBy($playerC)->shouldBe(false); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
public function it_is_satisfied_in_context_with_array(): void |
116
|
|
|
{ |
117
|
|
|
$game = ['name' => 'Tetris']; |
118
|
|
|
$player = ['pseudo' => 'Moe', 'gender' => 'M', 'points' => 1230, 'inGame' => $game]; |
119
|
|
|
|
120
|
|
|
$this->beConstructedWith('releaseAt', 'inGame'); |
121
|
|
|
|
122
|
|
|
$this->isSatisfiedBy($player)->shouldBe(true); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
View Code Duplication |
public function it_is_satisfied_in_context_with_object(): void |
|
|
|
|
126
|
|
|
{ |
127
|
|
|
$game = new Game('Tetris'); |
128
|
|
|
$player = new Player('Moe', 'M', 1230, $game); |
129
|
|
|
|
130
|
|
|
$this->beConstructedWith('releaseAt', 'inGame'); |
131
|
|
|
|
132
|
|
|
$this->isSatisfiedBy($player)->shouldBe(true); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
View Code Duplication |
public function it_filter_array_collection_in_context(): void |
|
|
|
|
136
|
|
|
{ |
137
|
|
|
$releaseAt = new \DateTimeImmutable(); |
138
|
|
|
$tetris = ['name' => 'Tetris', 'releaseAt' => null]; |
139
|
|
|
$mahjong = ['name' => 'Mahjong', 'releaseAt' => $releaseAt]; |
140
|
|
|
$players = [ |
141
|
|
|
['pseudo' => 'Joe', 'gender' => 'M', 'points' => 2500, 'inGame' => $mahjong], |
142
|
|
|
['pseudo' => 'Moe', 'gender' => 'M', 'points' => 1230, 'inGame' => $mahjong], |
143
|
|
|
['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001, 'inGame' => $tetris], |
144
|
|
|
]; |
145
|
|
|
|
146
|
|
|
$this->beConstructedWith('releaseAt', 'inGame'); |
147
|
|
|
|
148
|
|
|
$this->filterCollection($players)->shouldYield([$players[2]]); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
View Code Duplication |
public function it_filter_array_collection_in_global_context(): void |
|
|
|
|
152
|
|
|
{ |
153
|
|
|
$releaseAt = new \DateTimeImmutable(); |
154
|
|
|
$tetris = ['name' => 'Tetris', 'releaseAt' => null]; |
155
|
|
|
$mahjong = ['name' => 'Mahjong', 'releaseAt' => $releaseAt]; |
156
|
|
|
$players = [ |
157
|
|
|
['pseudo' => 'Joe', 'gender' => 'M', 'points' => 2500, 'inGame' => $mahjong], |
158
|
|
|
['pseudo' => 'Moe', 'gender' => 'M', 'points' => 1230, 'inGame' => $mahjong], |
159
|
|
|
['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001, 'inGame' => $tetris], |
160
|
|
|
]; |
161
|
|
|
|
162
|
|
|
$this->beConstructedWith('releaseAt', null); |
163
|
|
|
|
164
|
|
|
$this->filterCollection($players, 'inGame')->shouldYield([$players[2]]); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
View Code Duplication |
public function it_is_satisfied_in_global_context(): void |
|
|
|
|
168
|
|
|
{ |
169
|
|
|
$game = ['name' => 'Tetris', 'releaseAt' => null]; |
170
|
|
|
$player = ['pseudo' => 'Moe', 'gender' => 'M', 'points' => 1230, 'inGame' => $game]; |
171
|
|
|
|
172
|
|
|
$this->beConstructedWith('releaseAt', null); |
173
|
|
|
|
174
|
|
|
$this->isSatisfiedBy($player, 'inGame')->shouldBe(true); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
View Code Duplication |
public function it_filter_array_collection_in_combo_context(): void |
|
|
|
|
178
|
|
|
{ |
179
|
|
|
$tetrisOwner = ['name' => 'ABC', 'based' => null]; |
180
|
|
|
$mahjongOwner = ['name' => 'DEF', 'based' => 321]; |
181
|
|
|
$tetris = ['name' => 'Tetris', 'owner' => $tetrisOwner]; |
182
|
|
|
$mahjong = ['name' => 'Mahjong', 'owner' => $mahjongOwner]; |
183
|
|
|
$players = [ |
184
|
|
|
['pseudo' => 'Joe', 'gender' => 'M', 'points' => 2500, 'inGame' => $mahjong], |
185
|
|
|
['pseudo' => 'Moe', 'gender' => 'M', 'points' => 1230, 'inGame' => $mahjong], |
186
|
|
|
['pseudo' => 'Alice', 'gender' => 'F', 'points' => 9001, 'inGame' => $tetris], |
187
|
|
|
]; |
188
|
|
|
|
189
|
|
|
$this->beConstructedWith('based', 'owner'); |
190
|
|
|
|
191
|
|
|
$this->filterCollection($players, 'inGame')->shouldYield([$players[2]]); |
192
|
|
|
} |
193
|
|
|
|
194
|
|
View Code Duplication |
public function it_is_satisfied_in_combo_context(): void |
|
|
|
|
195
|
|
|
{ |
196
|
|
|
$owner = ['name' => 'ABC', 'based' => null]; |
197
|
|
|
$game = ['name' => 'Tetris', 'owner' => $owner]; |
198
|
|
|
$player = ['pseudo' => 'Moe', 'gender' => 'M', 'points' => 1230, 'inGame' => $game]; |
199
|
|
|
|
200
|
|
|
$this->beConstructedWith('based', 'owner'); |
201
|
|
|
|
202
|
|
|
$this->isSatisfiedBy($player, 'inGame')->shouldBe(true); |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
|
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.