1 | <?php |
||||
2 | declare(strict_types = 1); |
||||
3 | |||||
4 | namespace Tests\Innmind\Immutable; |
||||
5 | |||||
6 | use Innmind\Immutable\Maybe; |
||||
7 | use PHPUnit\Framework\TestCase; |
||||
8 | use Innmind\BlackBox\{ |
||||
9 | PHPUnit\BlackBox, |
||||
10 | Set, |
||||
11 | }; |
||||
12 | |||||
13 | class MaybeTest extends TestCase |
||||
14 | { |
||||
15 | use BlackBox; |
||||
16 | |||||
17 | public function testMapIsNotCalledWhenNoValue() |
||||
18 | { |
||||
19 | $maybe = Maybe::nothing(); |
||||
20 | |||||
21 | $this->assertInstanceOf(Maybe::class, $maybe->map(static function() { |
||||
22 | throw new \Exception; |
||||
23 | })); |
||||
24 | } |
||||
25 | |||||
26 | public function testMaybeNothingMatch() |
||||
27 | { |
||||
28 | $this |
||||
29 | ->forAll( |
||||
30 | $this->value(), |
||||
31 | $this->value(), |
||||
32 | ) |
||||
33 | ->then(function($unwanted, $nothing) { |
||||
34 | $this->assertSame( |
||||
35 | $nothing, |
||||
36 | Maybe::nothing()->match( |
||||
37 | static fn() => $unwanted, |
||||
38 | static fn() => $nothing, |
||||
39 | ), |
||||
40 | ); |
||||
41 | }); |
||||
42 | } |
||||
43 | |||||
44 | public function testMaybeOfNullReturnsANothingImplementation() |
||||
45 | { |
||||
46 | $this |
||||
47 | ->forAll( |
||||
48 | $this->value(), |
||||
49 | $this->value(), |
||||
50 | ) |
||||
51 | ->then(function($unwanted, $nothing) { |
||||
52 | $this->assertSame( |
||||
53 | $nothing, |
||||
54 | Maybe::of(null)->match( |
||||
55 | static fn() => $unwanted, |
||||
56 | static fn() => $nothing, |
||||
57 | ), |
||||
58 | ); |
||||
59 | }); |
||||
60 | } |
||||
61 | |||||
62 | public function testMaybeJustMatch() |
||||
63 | { |
||||
64 | $this |
||||
65 | ->forAll( |
||||
66 | $this->value(), |
||||
67 | $this->value(), |
||||
68 | $this->value(), |
||||
69 | ) |
||||
70 | ->then(function($initial, $just, $nothing) { |
||||
71 | $this->assertSame( |
||||
72 | $just, |
||||
73 | Maybe::just($initial)->match( |
||||
74 | function($value) use ($initial, $just) { |
||||
75 | $this->assertSame($initial, $value); |
||||
76 | |||||
77 | return $just; |
||||
78 | }, |
||||
79 | static fn() => $nothing, |
||||
80 | ), |
||||
81 | ); |
||||
82 | }); |
||||
83 | } |
||||
84 | |||||
85 | public function testMaybeOfValueReturnsAJustImplementation() |
||||
86 | { |
||||
87 | $this |
||||
88 | ->forAll( |
||||
89 | $this->value(), |
||||
90 | $this->value(), |
||||
91 | $this->value(), |
||||
92 | ) |
||||
93 | ->then(function($initial, $just, $nothing) { |
||||
94 | $this->assertSame( |
||||
95 | $just, |
||||
96 | Maybe::of($initial)->match( |
||||
97 | static fn() => $just, |
||||
98 | static fn() => $nothing, |
||||
99 | ), |
||||
100 | ); |
||||
101 | }); |
||||
102 | } |
||||
103 | |||||
104 | public function testMapIsCalledWhenThereIsAValue() |
||||
105 | { |
||||
106 | $this |
||||
107 | ->forAll( |
||||
108 | $this->value(), |
||||
109 | $this->value(), |
||||
110 | $this->value(), |
||||
111 | ) |
||||
112 | ->then(function($initial, $mapped, $unwanted) { |
||||
113 | $maybe = Maybe::just($initial); |
||||
114 | $maybe2 = $maybe->map(function($value) use ($initial, $mapped) { |
||||
115 | $this->assertSame($initial, $value); |
||||
116 | |||||
117 | return $mapped; |
||||
118 | }); |
||||
119 | |||||
120 | $this->assertInstanceOf(Maybe::class, $maybe2); |
||||
121 | $this->assertNotSame($maybe, $maybe2); |
||||
122 | $this->assertSame( |
||||
123 | $mapped, |
||||
124 | $maybe2->match( |
||||
125 | static fn($value) => $value, |
||||
126 | static fn() => $unwanted, |
||||
127 | ), |
||||
128 | ); |
||||
129 | }); |
||||
130 | } |
||||
131 | |||||
132 | public function testFlatMapIsNotCalledWhenNoValue() |
||||
133 | { |
||||
134 | $this->assertInstanceOf(Maybe::class, Maybe::nothing()->flatMap(static function() { |
||||
135 | throw new \Exception; |
||||
136 | })); |
||||
137 | } |
||||
138 | |||||
139 | public function testFlatMapIsCalledWhenThereIsAValue() |
||||
140 | { |
||||
141 | $this |
||||
142 | ->forAll( |
||||
143 | $this->value(), |
||||
144 | $this->value(), |
||||
145 | $this->value(), |
||||
146 | ) |
||||
147 | ->then(function($initial, $mapped, $nothing) { |
||||
148 | $expected = Maybe::just($mapped); |
||||
149 | $maybe = Maybe::just($initial)->flatMap(function($value) use ($initial, $expected) { |
||||
150 | $this->assertSame($initial, $value); |
||||
151 | |||||
152 | return $expected; |
||||
153 | }); |
||||
154 | |||||
155 | $this->assertSame($expected, $maybe); |
||||
156 | $this->assertSame( |
||||
157 | $mapped, |
||||
158 | $maybe->match( |
||||
159 | static fn($value) => $value, |
||||
160 | static fn() => $nothing, |
||||
161 | ), |
||||
162 | ); |
||||
163 | }); |
||||
164 | } |
||||
165 | |||||
166 | public function testOtherwiseIsCalledWhenNoValue() |
||||
167 | { |
||||
168 | $this |
||||
169 | ->forAll(Set\AnyType::any()) |
||||
170 | ->then(function($value) { |
||||
171 | $expected = Maybe::of($value); |
||||
172 | |||||
173 | $this->assertSame( |
||||
174 | $expected, |
||||
175 | Maybe::nothing()->otherwise(static fn() => $expected), |
||||
176 | ); |
||||
177 | }); |
||||
178 | } |
||||
179 | |||||
180 | public function testOtherwiseIsNotCalledWhenThereIsAValue() |
||||
181 | { |
||||
182 | $this |
||||
183 | ->forAll( |
||||
184 | $this->value(), |
||||
185 | $this->value(), |
||||
186 | ) |
||||
187 | ->then(function($initial, $nothing) { |
||||
188 | $maybe = Maybe::just($initial); |
||||
189 | $maybe2 = $maybe->otherwise(static function() { |
||||
190 | throw new \Exception; |
||||
191 | }); |
||||
192 | |||||
193 | $this->assertInstanceOf(Maybe::class, $maybe2); |
||||
194 | $this->assertNotSame($maybe, $maybe2); |
||||
195 | $this->assertSame( |
||||
196 | $initial, |
||||
197 | $maybe2->match( |
||||
198 | static fn($value) => $value, |
||||
199 | static fn() => $nothing, |
||||
200 | ), |
||||
201 | ); |
||||
202 | }); |
||||
203 | } |
||||
204 | |||||
205 | public function testFilterPredicateIsNotCalledWhenNoValue() |
||||
206 | { |
||||
207 | $this->assertInstanceOf(Maybe::class, Maybe::nothing()->filter(static function() { |
||||
208 | throw new \Exception; |
||||
209 | })); |
||||
210 | } |
||||
211 | |||||
212 | public function testReturnItselfWhenFilterPredicateReturnsTrue() |
||||
213 | { |
||||
214 | $this |
||||
215 | ->forAll( |
||||
216 | $this->value(), |
||||
217 | $this->value(), |
||||
218 | ) |
||||
219 | ->then(function($initial, $nothing) { |
||||
220 | $maybe = Maybe::just($initial)->filter(function($value) use ($initial) { |
||||
221 | $this->assertSame($initial, $value); |
||||
222 | |||||
223 | return true; |
||||
224 | }); |
||||
225 | |||||
226 | $this->assertInstanceOf(Maybe::class, $maybe); |
||||
227 | $this->assertSame( |
||||
228 | $initial, |
||||
229 | $maybe->match( |
||||
230 | static fn($value) => $value, |
||||
231 | static fn() => $nothing, |
||||
232 | ), |
||||
233 | ); |
||||
234 | }); |
||||
235 | } |
||||
236 | |||||
237 | public function testReturnsANothingWhenFilterPredicateReturnsFalse() |
||||
238 | { |
||||
239 | $this |
||||
240 | ->forAll( |
||||
241 | $this->value(), |
||||
242 | $this->value(), |
||||
243 | ) |
||||
244 | ->then(function($initial, $nothing) { |
||||
245 | $maybe = Maybe::just($initial)->filter(function($value) use ($initial) { |
||||
246 | $this->assertSame($initial, $value); |
||||
247 | |||||
248 | return false; |
||||
249 | }); |
||||
250 | |||||
251 | $this->assertInstanceOf(Maybe::class, $maybe); |
||||
252 | $this->assertSame( |
||||
253 | $nothing, |
||||
254 | $maybe->match( |
||||
255 | static fn($value) => $value, |
||||
256 | static fn() => $nothing, |
||||
257 | ), |
||||
258 | ); |
||||
259 | }); |
||||
260 | } |
||||
261 | |||||
262 | public function testAllMapKeepValuesOrder() |
||||
263 | { |
||||
264 | $this |
||||
265 | ->forAll(Set\Sequence::of( |
||||
266 | $this->value(), |
||||
267 | Set\Integers::between(1, 5), |
||||
268 | )) |
||||
269 | ->then(function($expected) { |
||||
270 | $maybes = \array_map( |
||||
271 | static fn($value) => Maybe::just($value), |
||||
272 | $expected, |
||||
273 | ); |
||||
274 | |||||
275 | $comprehension = Maybe::all(...$maybes); |
||||
276 | |||||
277 | $this->assertInstanceOf(Maybe\Comprehension::class, $comprehension); |
||||
278 | $maybe = $comprehension->map(function(...$args) use ($expected) { |
||||
279 | $this->assertSame($expected, $args); |
||||
280 | |||||
281 | return $args[0]; |
||||
282 | }); |
||||
283 | $this->assertInstanceOf(Maybe::class, $maybe); |
||||
284 | }); |
||||
285 | } |
||||
286 | |||||
287 | public function testAllFlatMapKeepValuesOrder() |
||||
288 | { |
||||
289 | $this |
||||
290 | ->forAll(Set\Sequence::of( |
||||
291 | $this->value(), |
||||
292 | Set\Integers::between(1, 5), |
||||
293 | )) |
||||
294 | ->then(function($expected) { |
||||
295 | $maybes = \array_map( |
||||
296 | static fn($value) => Maybe::just($value), |
||||
297 | $expected, |
||||
298 | ); |
||||
299 | |||||
300 | $comprehension = Maybe::all(...$maybes); |
||||
301 | |||||
302 | $this->assertInstanceOf(Maybe\Comprehension::class, $comprehension); |
||||
303 | $maybe = $comprehension->flatMap(function(...$args) use ($expected) { |
||||
304 | $this->assertSame($expected, $args); |
||||
305 | |||||
306 | return Maybe::just($args[0]); |
||||
307 | }); |
||||
308 | $this->assertInstanceOf(Maybe::class, $maybe); |
||||
309 | }); |
||||
310 | } |
||||
311 | |||||
312 | public function testAllMapResult() |
||||
313 | { |
||||
314 | $this |
||||
315 | ->forAll( |
||||
316 | Set\Sequence::of( |
||||
317 | Set\Decorate::immutable( |
||||
318 | static fn($value) => Maybe::just($value), |
||||
319 | $this->value(), |
||||
320 | ), |
||||
321 | Set\Integers::between(1, 5), |
||||
322 | ), |
||||
323 | $this->value(), |
||||
324 | ) |
||||
325 | ->then(function($maybes, $expected) { |
||||
326 | $comprehension = Maybe::all(...$maybes); |
||||
327 | |||||
328 | $this->assertInstanceOf(Maybe\Comprehension::class, $comprehension); |
||||
329 | $maybe = $comprehension->map(static fn(...$args) => $expected); |
||||
0 ignored issues
–
show
|
|||||
330 | $this->assertSame($expected, $maybe->match( |
||||
331 | static fn($value) => $value, |
||||
332 | static fn() => null, |
||||
333 | )); |
||||
334 | }); |
||||
335 | } |
||||
336 | |||||
337 | public function testAllFlatMapResult() |
||||
338 | { |
||||
339 | $this |
||||
340 | ->forAll( |
||||
341 | Set\Sequence::of( |
||||
342 | Set\Decorate::immutable( |
||||
343 | static fn($value) => Maybe::just($value), |
||||
344 | $this->value(), |
||||
345 | ), |
||||
346 | Set\Integers::between(1, 5), |
||||
347 | ), |
||||
348 | new Set\Either( |
||||
349 | Set\Elements::of(Maybe::nothing()), |
||||
350 | Set\Decorate::immutable( |
||||
351 | static fn($value) => Maybe::just($value), |
||||
352 | $this->value(), |
||||
353 | ), |
||||
354 | ), |
||||
355 | ) |
||||
356 | ->then(function($maybes, $expected) { |
||||
357 | $comprehension = Maybe::all(...$maybes); |
||||
358 | |||||
359 | $this->assertInstanceOf(Maybe\Comprehension::class, $comprehension); |
||||
360 | $maybe = $comprehension->flatMap(static fn(...$args) => $expected); |
||||
0 ignored issues
–
show
The parameter
$args is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
361 | $this->assertSame($expected, $maybe); |
||||
362 | }); |
||||
363 | } |
||||
364 | |||||
365 | public function testAllMapNotCalledWhenOneNothingIsPresent() |
||||
366 | { |
||||
367 | $this |
||||
368 | ->forAll(Set\Sequence::of( |
||||
369 | Set\Decorate::immutable( |
||||
370 | static fn($value) => Maybe::just($value), |
||||
371 | $this->value(), |
||||
372 | ), |
||||
373 | Set\Integers::between(1, 5), |
||||
374 | )) |
||||
375 | ->then(function($maybes) { |
||||
376 | $maybes[] = Maybe::nothing(); |
||||
377 | $comprehension = Maybe::all(...$maybes); |
||||
378 | |||||
379 | $this->assertInstanceOf(Maybe\Comprehension::class, $comprehension); |
||||
380 | $called = false; |
||||
381 | $comprehension->map(static function(...$args) use (&$called) { |
||||
382 | $called = true; |
||||
383 | |||||
384 | return $args[0]; |
||||
385 | }); |
||||
386 | $this->assertFalse($called); |
||||
387 | }); |
||||
388 | } |
||||
389 | |||||
390 | public function testAllFlatMapNotCalledWhenOneNothingIsPresent() |
||||
391 | { |
||||
392 | $this |
||||
393 | ->forAll(Set\Sequence::of( |
||||
394 | Set\Decorate::immutable( |
||||
395 | static fn($value) => Maybe::just($value), |
||||
396 | $this->value(), |
||||
397 | ), |
||||
398 | Set\Integers::between(1, 5), |
||||
399 | )) |
||||
400 | ->then(function($maybes) { |
||||
401 | $maybes[] = Maybe::nothing(); |
||||
402 | $comprehension = Maybe::all(...$maybes); |
||||
403 | |||||
404 | $this->assertInstanceOf(Maybe\Comprehension::class, $comprehension); |
||||
405 | $called = false; |
||||
406 | $comprehension->flatMap(static function(...$args) use (&$called) { |
||||
407 | $called = true; |
||||
408 | |||||
409 | return Maybe::just($args[0]); |
||||
410 | }); |
||||
411 | $this->assertFalse($called); |
||||
412 | }); |
||||
413 | } |
||||
414 | |||||
415 | private function value(): Set |
||||
416 | { |
||||
417 | return Set\AnyType::any()->filter(static fn($value) => $value !== null); |
||||
418 | } |
||||
419 | } |
||||
420 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.