@@ -218,12 +218,12 @@ public function call(callable $callable, array $bindings = []): mixed
218218 expect ($ container ->get ('date ' ) === $ container ->get ('date ' ))->toBeTrue (); // The same instance is returned every time
219219 });
220220
221- it ('should not override previously defined instances ' , function () {
221+ it ('should override previously defined instances ' , function () {
222222 $ container = new CascadeContainer ();
223223 $ container ->set ('container ' , $ container );
224224 $ container ->deferred ('container ' , fn () => new NullContainer ());
225225
226- expect ($ container ->get ('container ' ))->toBe ( $ container );
226+ expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer::class );
227227 });
228228
229229 it ('should override previously defined factories ' , function () {
@@ -243,14 +243,14 @@ public function call(callable $callable, array $bindings = []): mixed
243243 expect ($ container ->get ('container ' ))->toBe ($ container );
244244 });
245245
246- it ('it should not override previously defined resolved deferred resolvers ' , function () {
246+ it ('it should override previously defined resolved deferred resolvers ' , function () {
247247 $ container = new CascadeContainer ();
248248
249249 $ container ->deferred ('container ' , fn () => new NullContainer ());
250250 expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer::class);
251251
252252 $ container ->deferred ('container ' , fn () => $ container );
253- expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer ::class);
253+ expect ($ container ->get ('container ' ))->toBeInstanceOf (CascadeContainer ::class);
254254 });
255255
256256 it ('should take precedence over parent container ' , function () {
@@ -289,12 +289,12 @@ public function call(callable $callable, array $bindings = []): mixed
289289 expect ($ container ->get ('date ' ) === $ container ->get ('date ' ))->toBeFalse (); // A new instance is returned every time
290290 });
291291
292- it ('should not override previously defined instances ' , function () {
292+ it ('should override previously defined instances ' , function () {
293293 $ container = new CascadeContainer ();
294294 $ container ->set ('container ' , $ container );
295295 $ container ->factory ('container ' , fn () => new NullContainer ());
296296
297- expect ($ container ->get ('container ' ))->toBe ( $ container );
297+ expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer::class );
298298 });
299299
300300 it ('should override previously defined factories ' , function () {
@@ -313,15 +313,14 @@ public function call(callable $callable, array $bindings = []): mixed
313313 expect ($ container ->get ('container ' ))->toBe ($ container );
314314 });
315315
316- it ('it should not override previously defined resolved deferred resolvers ' , function () {
316+ it ('it should override previously defined resolved deferred resolvers ' , function () {
317317 $ container = new CascadeContainer ();
318318
319319 $ container ->deferred ('container ' , fn () => new NullContainer ());
320320 expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer::class);
321321
322322 $ container ->factory ('container ' , fn () => $ container );
323-
324- expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer::class);
323+ expect ($ container ->get ('container ' ))->toBe ($ container );
325324 });
326325
327326 it ('should take precedence over parent container ' , function () {
@@ -351,6 +350,91 @@ public function call(callable $callable, array $bindings = []): mixed
351350 });
352351});
353352
353+ describe ('CascadeContainer::extend() ' , function () {
354+ it ('should extend the existing service instance ' , function () {
355+ $ container = new CascadeContainer ();
356+ $ container ->set ('container ' , new NullContainer ());
357+
358+ expect ($ container ->get ('container ' ))->toBeInstanceOf (NullContainer::class);
359+
360+ $ container ->extend ('container ' , function ($ container ) {
361+ expect ($ container )->toBeInstanceOf (NullContainer::class);
362+
363+ return new CascadeContainer (parent: $ container );
364+ });
365+
366+ expect ($ container ->get ('container ' ))->toBeInstanceOf (CascadeContainer::class);
367+ });
368+
369+ it ('should extend deferred service resolvers ' , function () {
370+ $ container = new CascadeContainer ();
371+ $ container ->deferred ('container ' , fn () => new NullContainer ());
372+
373+ $ container ->extend ('container ' , function ($ container ) {
374+ expect ($ container )->toBeInstanceOf (NullContainer::class);
375+
376+ return new CascadeContainer (parent: $ container );
377+ });
378+
379+ expect ($ container ->get ('container ' ))->toBeInstanceOf (CascadeContainer::class);
380+ });
381+
382+ it ('should extend service factories ' , function () {
383+ $ container = new CascadeContainer ();
384+
385+ $ container ->factory ('date ' , fn () => new DateTime ('now ' ));
386+
387+ $ container ->extend ('date ' , function ($ date ) {
388+ expect ($ date )->toBeInstanceOf (DateTime::class);
389+
390+ $ date ->setTimezone (new DateTimeZone ('Europe/Madrid ' ));
391+
392+ return $ date ;
393+ });
394+
395+ expect ($ container ->get ('date ' ))->toBeInstanceOf (DateTime::class);
396+ expect ($ container ->get ('date ' )->getTimeZone ())->toEqual (new DateTimeZone ('Europe/Madrid ' ));
397+
398+ expect ($ container ->get ('date ' ) !== $ container ->get ('date ' ))->toBeTrue ();
399+ });
400+
401+ it ('should extend services by their aliases ' , function () {
402+ $ container = new CascadeContainer ();
403+
404+ $ container ->set ('container ' , $ container );
405+ $ container ->alias ('container ' , alias: ContainerInterface::class);
406+
407+ $ container ->extend (ContainerInterface::class, function ($ container ) {
408+ expect ($ container )->toBeInstanceOf (CascadeContainer::class);
409+
410+ assert ($ container instanceof CascadeContainer);
411+
412+ return $ container ->cascade ();
413+ });
414+
415+ expect ($ container ->get ('container ' ))->toBeInstanceOf (CascadeContainer::class);
416+ expect ($ container ->get (ContainerInterface::class))->toBeInstanceOf (CascadeContainer::class);
417+
418+ expect ($ container ->get ('container ' ) === $ container ->get (ContainerInterface::class))->toBeTrue ();
419+ expect ($ container ->get ('container ' ) === $ container )->toBeFalse ();
420+ });
421+
422+ it ('it should call a callback function auto-wiring its arguments ' , function () {
423+ $ container = new CascadeContainer ();
424+ $ container ->deferred (DateTime::class, fn () => new DateTime ('2025-01-01T12:00:00Z ' ));
425+ $ container ->factory (ContainerInterface::class, fn () => new NullContainer ());
426+
427+ $ container ->extend (ContainerInterface::class, function (ContainerInterface $ container , DateTime $ date ) {
428+ expect ($ date )->toEqual (new DateTime ('2025-01-01T12:00:00Z ' ));
429+ expect ($ container )->toBeInstanceOf (NullContainer::class);
430+
431+ return new ArrayContainer ();
432+ });
433+
434+ expect ($ container ->get (ContainerInterface::class))->toBeInstanceOf (ArrayContainer::class);
435+ });
436+ });
437+
354438describe ('CascadeContainer::resolve() ' , function () {
355439 it ('it should get an instance from the container when defined ' , function () {
356440 $ container = new CascadeContainer ();
0 commit comments