@@ -178,11 +178,12 @@ public function testFoldLeftRight(): void
178178 $ callback = function () {
179179 };
180180
181- $ option = self ::getMockForAbstractClass (Option::class);
181+ // Use TestOption as a concrete implementation to test with
182+ $ option = self ::createPartialMock (TestOption::class, ['foldLeft ' , 'foldRight ' ]);
182183 $ option ->expects (self ::once ())
183184 ->method ('foldLeft ' )
184185 ->with (5 , $ callback )
185- ->will ( self :: returnValue ( 6 ) );
186+ ->willReturn ( 6 );
186187 $ lazyOption = new LazyOption (function () use ($ option ) {
187188 return $ option ;
188189 });
@@ -191,10 +192,126 @@ public function testFoldLeftRight(): void
191192 $ option ->expects (self ::once ())
192193 ->method ('foldRight ' )
193194 ->with (5 , $ callback )
194- ->will ( self :: returnValue ( 6 ) );
195+ ->willReturn ( 6 );
195196 $ lazyOption = new LazyOption (function () use ($ option ) {
196197 return $ option ;
197198 });
198199 self ::assertSame (6 , $ lazyOption ->foldRight (5 , $ callback ));
199200 }
200201}
202+
203+ class TestOption extends Option
204+ {
205+ private $ value ;
206+
207+ public function __construct ($ value = null )
208+ {
209+ $ this ->value = $ value ;
210+ }
211+
212+ public function get ()
213+ {
214+ return $ this ->value ;
215+ }
216+
217+ public function getOrElse ($ default )
218+ {
219+ return $ this ->isDefined () ? $ this ->value : $ default ;
220+ }
221+
222+ public function getOrCall ($ callable )
223+ {
224+ return $ this ->isDefined () ? $ this ->value : call_user_func ($ callable );
225+ }
226+
227+ public function getOrThrow (\Exception $ ex )
228+ {
229+ if ($ this ->isDefined ()) {
230+ return $ this ->value ;
231+ }
232+ throw $ ex ;
233+ }
234+
235+ public function isEmpty ()
236+ {
237+ return $ this ->value === null ;
238+ }
239+
240+ public function isDefined ()
241+ {
242+ return $ this ->value !== null ;
243+ }
244+
245+ public function orElse (Option $ else )
246+ {
247+ return $ this ->isDefined () ? $ this : $ else ;
248+ }
249+
250+ public function ifDefined ($ callable )
251+ {
252+ if ($ this ->isDefined ()) {
253+ call_user_func ($ callable , $ this ->value );
254+ }
255+ }
256+
257+ public function forAll ($ callable )
258+ {
259+ if ($ this ->isDefined ()) {
260+ call_user_func ($ callable , $ this ->value );
261+ }
262+ }
263+
264+ public function map ($ callable )
265+ {
266+ return $ this ->isDefined () ? new self (call_user_func ($ callable , $ this ->value )) : $ this ;
267+ }
268+
269+ public function flatMap ($ callable )
270+ {
271+ return $ this ->isDefined () ? call_user_func ($ callable , $ this ->value ) : $ this ;
272+ }
273+
274+ public function filter ($ callable )
275+ {
276+ return $ this ->isDefined () && call_user_func ($ callable , $ this ->value ) ? $ this : None::create ();
277+ }
278+
279+ public function filterNot ($ callable )
280+ {
281+ return $ this ->isDefined () && !call_user_func ($ callable , $ this ->value ) ? $ this : None::create ();
282+ }
283+
284+ public function select ($ value )
285+ {
286+ return $ this ->isDefined () && $ this ->value === $ value ? $ this : None::create ();
287+ }
288+
289+ public function reject ($ value )
290+ {
291+ return $ this ->isDefined () && $ this ->value !== $ value ? $ this : None::create ();
292+ }
293+
294+ public function foldLeft ($ initialValue , $ callable )
295+ {
296+ if ($ this ->isDefined ()) {
297+ return call_user_func ($ callable , $ initialValue , $ this ->value );
298+ }
299+ return $ initialValue ;
300+ }
301+
302+ public function foldRight ($ initialValue , $ callable )
303+ {
304+ if ($ this ->isDefined ()) {
305+ return call_user_func ($ callable , $ this ->value , $ initialValue );
306+ }
307+ return $ initialValue ;
308+ }
309+
310+ public function getIterator (): \Traversable
311+ {
312+ if ($ this ->isDefined ()) {
313+ return new \ArrayIterator ([$ this ->value ]);
314+ }
315+ return new \ArrayIterator ([]);
316+ }
317+ }
0 commit comments