22
33declare (strict_types=1 );
44
5- /**
6- * This file is part of php-fast-forward/container.
7- *
8- * This source file is subject to the license bundled
9- * with this source code in the file LICENSE.
10- *
11- * @link https://github.com/php-fast-forward/container
12- * @copyright Copyright (c) 2025 Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
13- * @license https://opensource.org/licenses/MIT MIT License
14- */
15-
165namespace FastForward \Container \Tests \Factory ;
176
187use FastForward \Container \Exception \RuntimeException ;
2312use Prophecy \PhpUnit \ProphecyTrait ;
2413use Psr \Container \ContainerInterface ;
2514
26- /**
27- * @internal
28- */
2915#[CoversClass(MethodFactory::class)]
3016#[UsesClass(RuntimeException::class)]
3117final class MethodFactoryTest extends TestCase
@@ -34,14 +20,14 @@ final class MethodFactoryTest extends TestCase
3420
3521 public function testInvokeInstanceMethod (): void
3622 {
37- $ service = new MethodTarget ();
23+ $ service = new MethodFactoryTestTargetStub ();
3824
3925 $ container = $ this ->prophesize (ContainerInterface::class);
4026 $ container ->has ('prefix ' )->willReturn (false );
41- $ container ->has (MethodTarget ::class)->willReturn (true );
42- $ container ->get (MethodTarget ::class)->willReturn ($ service );
27+ $ container ->has (MethodFactoryTestTargetStub ::class)->willReturn (true );
28+ $ container ->get (MethodFactoryTestTargetStub ::class)->willReturn ($ service );
4329
44- $ factory = new MethodFactory (MethodTarget ::class, 'instanceMethod ' , 'prefix ' );
30+ $ factory = new MethodFactory (MethodFactoryTestTargetStub ::class, 'instanceMethod ' , 'prefix ' );
4531
4632 $ result = $ factory ($ container ->reveal ());
4733
@@ -51,10 +37,9 @@ public function testInvokeInstanceMethod(): void
5137 public function testInvokeStaticMethod (): void
5238 {
5339 $ container = $ this ->prophesize (ContainerInterface::class);
54- $ container ->has (MethodTarget::class)->willReturn (false );
5540 $ container ->has ('value ' )->willReturn (false );
5641
57- $ factory = new MethodFactory (MethodTarget ::class, 'staticMethod ' , 'value ' );
42+ $ factory = new MethodFactory (MethodFactoryTestTargetStub ::class, 'staticMethod ' , 'value ' );
5843
5944 $ result = $ factory ($ container ->reveal ());
6045
@@ -63,16 +48,16 @@ public function testInvokeStaticMethod(): void
6348
6449 public function testInvokeResolvesArgumentsFromContainer (): void
6550 {
66- $ service = new MethodTarget ();
51+ $ service = new MethodFactoryTestTargetStub ();
6752 $ argObj = new \stdClass ();
6853
6954 $ container = $ this ->prophesize (ContainerInterface::class);
70- $ container ->has (MethodTarget ::class)->willReturn (true );
71- $ container ->get (MethodTarget ::class)->willReturn ($ service );
55+ $ container ->has (MethodFactoryTestTargetStub ::class)->willReturn (true );
56+ $ container ->get (MethodFactoryTestTargetStub ::class)->willReturn ($ service );
7257 $ container ->has ('dependency ' )->willReturn (true );
7358 $ container ->get ('dependency ' )->willReturn ($ argObj );
7459
75- $ factory = new MethodFactory (MethodTarget ::class, 'acceptsObject ' , 'dependency ' );
60+ $ factory = new MethodFactory (MethodFactoryTestTargetStub ::class, 'acceptsObject ' , 'dependency ' );
7661
7762 $ result = $ factory ($ container ->reveal ());
7863
@@ -81,23 +66,50 @@ public function testInvokeResolvesArgumentsFromContainer(): void
8166
8267 public function testInvokeThrowsForNonPublicMethod (): void
8368 {
84- $ service = new MethodTarget ();
85-
8669 $ container = $ this ->prophesize (ContainerInterface::class);
87- $ container ->has (MethodTarget::class)->willReturn (true );
88- $ container ->get (MethodTarget::class)->willReturn ($ service );
70+ $ container ->has (MethodFactoryTestTargetStub::class)->willReturn (false );
8971
90- $ factory = new MethodFactory (MethodTarget ::class, 'privateMethod ' );
72+ $ factory = new MethodFactory (MethodFactoryTestTargetStub ::class, 'privateMethod ' );
9173
9274 $ this ->expectException (RuntimeException::class);
93- $ this ->expectExceptionMessage ('Method "FastForward\Container\Tests\Factory\MethodTarget::privateMethod" MUST be public to be invoked as a service. ' );
9475
9576 $ factory ($ container ->reveal ());
9677 }
78+
79+ public function testInvokeWillConstructTargetIfContainerDoesNotProvide (): void
80+ {
81+ $ container = $ this ->prophesize (ContainerInterface::class);
82+ $ container ->has ('prefix ' )->willReturn (false );
83+ $ container ->get (MethodFactoryTestTargetStub::class)->willThrow (new \Exception ());
84+
85+ $ factory = new MethodFactory (MethodFactoryTestTargetStub::class, 'instanceMethod ' , 'prefix ' );
86+
87+ $ result = $ factory ($ container ->reveal ());
88+
89+ self ::assertSame ('prefix-instance ' , $ result );
90+ }
91+
92+ public function testConstructorDependencyIsResolvedFromContainer (): void
93+ {
94+ $ dependency = new MethodFactoryTestDependencyStub ();
95+
96+ $ container = $ this ->prophesize (ContainerInterface::class);
97+ $ container ->has (MethodFactoryTestTargetStub::class)->willReturn (true );
98+ $ container ->get (MethodFactoryTestTargetStub::class)->willReturn (new MethodFactoryTestTargetStub ($ dependency ))->shouldBeCalledOnce ();
99+ $ container ->has ('suffix ' )->willReturn (false );
100+
101+ $ factory = new MethodFactory (MethodFactoryTestTargetStub::class, 'usesConstructorArgument ' , 'suffix ' );
102+
103+ $ result = $ factory ($ container ->reveal ());
104+
105+ self ::assertSame (MethodFactoryTestDependencyStub::class . '-suffix ' , $ result );
106+ }
97107}
98108
99- class MethodTarget
109+ class MethodFactoryTestTargetStub
100110{
111+ public function __construct (private ?MethodFactoryTestDependencyStub $ dependency = null ) {}
112+
101113 public function instanceMethod (string $ prefix ): string
102114 {
103115 return $ prefix . '-instance ' ;
@@ -113,5 +125,14 @@ public function acceptsObject(object $obj): object
113125 return $ obj ;
114126 }
115127
128+ public function usesConstructorArgument (string $ suffix ): string
129+ {
130+ return $ this ->dependency ::class . '- ' . $ suffix ;
131+ }
132+
116133 private function privateMethod (): void {}
117134}
135+
136+ class MethodFactoryTestDependencyStub
137+ {
138+ }
0 commit comments