5
5
namespace Codeception \Lib \Connector ;
6
6
7
7
use InvalidArgumentException ;
8
- use ReflectionClass ;
8
+ use LogicException ;
9
9
use ReflectionMethod ;
10
10
use ReflectionProperty ;
11
11
use Symfony \Bundle \FrameworkBundle \Test \TestContainer ;
12
12
use Symfony \Component \DependencyInjection \ContainerInterface ;
13
- use Symfony \Component \HttpFoundation \Request ;
14
13
use Symfony \Component \HttpFoundation \Response ;
15
14
use Symfony \Component \HttpKernel \HttpKernelBrowser ;
16
15
use Symfony \Component \HttpKernel \Kernel ;
16
+ use Symfony \Component \HttpKernel \KernelInterface ;
17
17
use Symfony \Component \HttpKernel \Profiler \Profiler ;
18
- use function array_keys ;
18
+
19
19
use function codecept_debug ;
20
20
21
+ /**
22
+ * @property KernelInterface $kernel
23
+ */
21
24
class Symfony extends HttpKernelBrowser
22
25
{
26
+ private ContainerInterface $ container ;
23
27
private bool $ hasPerformedRequest = false ;
24
- private ?ContainerInterface $ container ;
25
28
29
+ /**
30
+ * @param Kernel $kernel
31
+ * @param array<string, object> $persistentServices
32
+ */
26
33
public function __construct (
27
- Kernel $ kernel ,
34
+ $ kernel ,
28
35
public array $ persistentServices = [],
29
- private readonly bool $ rebootable = true
36
+ private bool $ reboot = true
30
37
) {
31
38
parent ::__construct ($ kernel );
32
39
$ this ->followRedirects ();
33
- $ this ->container = $ this ->getContainer ();
40
+ $ this ->container = $ this ->resolveContainer ();
34
41
$ this ->rebootKernel ();
35
42
}
36
43
37
- /** @param Request $request */
38
44
protected function doRequest (object $ request ): Response
39
45
{
40
- if ($ this ->rebootable ) {
41
- if ($ this ->hasPerformedRequest ) {
42
- $ this ->rebootKernel ();
43
- } else {
44
- $ this ->hasPerformedRequest = true ;
45
- }
46
+ if ($ this ->reboot ) {
47
+ $ this ->hasPerformedRequest ? $ this ->rebootKernel () : $ this ->hasPerformedRequest = true ;
46
48
}
47
49
48
50
return parent ::doRequest ($ request );
@@ -57,30 +59,27 @@ protected function doRequest(object $request): Response
57
59
*/
58
60
public function rebootKernel (): void
59
61
{
60
- if ($ this ->container ) {
61
- foreach (array_keys ($ this ->persistentServices ) as $ serviceName ) {
62
- if ($ service = $ this ->getService ($ serviceName )) {
63
- $ this ->persistentServices [$ serviceName ] = $ service ;
64
- }
62
+ foreach (array_keys ($ this ->persistentServices ) as $ service ) {
63
+ if ($ this ->container ->has ($ service )) {
64
+ $ this ->persistentServices [$ service ] = $ this ->container ->get ($ service );
65
65
}
66
66
}
67
67
68
68
$ this ->persistDoctrineConnections ();
69
- $ this ->ensureKernelShutdown ();
70
- $ this ->kernel ->boot ();
71
- $ this ->container = $ this ->getContainer ();
72
-
73
- foreach ($ this ->persistentServices as $ serviceName => $ service ) {
69
+ if ($ this ->kernel instanceof Kernel) {
70
+ $ this ->ensureKernelShutdown ();
71
+ $ this ->kernel ->boot ();
72
+ }
73
+ $ this ->container = $ this ->resolveContainer ();
74
+ foreach ($ this ->persistentServices as $ name => $ service ) {
74
75
try {
75
- $ this ->container ->set ($ serviceName , $ service );
76
+ $ this ->container ->set ($ name , $ service );
76
77
} catch (InvalidArgumentException $ e ) {
77
- codecept_debug ("[Symfony] Can't set persistent service {$ serviceName }: " . $ e ->getMessage ());
78
+ codecept_debug ("[Symfony] Can't set persistent service {$ name }: { $ e ->getMessage ()}" );
78
79
}
79
80
}
80
81
81
- if ($ profiler = $ this ->getProfiler ()) {
82
- $ profiler ->enable ();
83
- }
82
+ $ this ->getProfiler ()?->enable();
84
83
}
85
84
86
85
protected function ensureKernelShutdown (): void
@@ -89,27 +88,25 @@ protected function ensureKernelShutdown(): void
89
88
$ this ->kernel ->shutdown ();
90
89
}
91
90
92
- private function getContainer (): ? ContainerInterface
91
+ private function resolveContainer (): ContainerInterface
93
92
{
94
- /** @var ContainerInterface $container */
95
93
$ container = $ this ->kernel ->getContainer ();
96
- return $ container ->has ('test.service_container ' )
97
- ? $ container ->get ('test.service_container ' )
98
- : $ container ;
99
- }
100
94
101
- private function getProfiler (): ?Profiler
102
- {
103
- return $ this ->container ->has ('profiler ' )
104
- ? $ this ->container ->get ('profiler ' )
105
- : null ;
95
+ if ($ container ->has ('test.service_container ' )) {
96
+ $ testContainer = $ container ->get ('test.service_container ' );
97
+ if (!$ testContainer instanceof ContainerInterface) {
98
+ throw new LogicException ('Service "test.service_container" must implement ' . ContainerInterface::class);
99
+ }
100
+ $ container = $ testContainer ;
101
+ }
102
+
103
+ return $ container ;
106
104
}
107
105
108
- private function getService ( string $ serviceName ): ?object
106
+ private function getProfiler ( ): ?Profiler
109
107
{
110
- return $ this ->container ->has ($ serviceName )
111
- ? $ this ->container ->get ($ serviceName )
112
- : null ;
108
+ $ profiler = $ this ->container ->get ('profiler ' );
109
+ return $ profiler instanceof Profiler ? $ profiler : null ;
113
110
}
114
111
115
112
private function persistDoctrineConnections (): void
@@ -119,20 +116,27 @@ private function persistDoctrineConnections(): void
119
116
}
120
117
121
118
if ($ this ->container instanceof TestContainer) {
122
- $ reflectedTestContainer = new ReflectionMethod ($ this ->container , 'getPublicContainer ' );
123
- $ reflectedTestContainer ->setAccessible (true );
124
- $ publicContainer = $ reflectedTestContainer ->invoke ($ this ->container );
119
+ $ method = new ReflectionMethod ($ this ->container , 'getPublicContainer ' );
120
+ $ publicContainer = $ method ->invoke ($ this ->container );
125
121
} else {
126
122
$ publicContainer = $ this ->container ;
127
123
}
128
124
129
- $ reflectedContainer = new ReflectionClass ($ publicContainer );
130
- $ reflectionTarget = $ reflectedContainer ->hasProperty ('parameters ' ) ? $ publicContainer : $ publicContainer ->getParameterBag ();
125
+ if (!is_object ($ publicContainer ) || !method_exists ($ publicContainer , 'getParameterBag ' )) {
126
+ return ;
127
+ }
128
+
129
+ $ target = property_exists ($ publicContainer , 'parameters ' )
130
+ ? $ publicContainer
131
+ : $ publicContainer ->getParameterBag ();
132
+
133
+ if (!is_object ($ target ) || !property_exists ($ target , 'parameters ' )) {
134
+ return ;
135
+ }
136
+ $ prop = new ReflectionProperty ($ target , 'parameters ' );
131
137
132
- $ reflectedParameters = new ReflectionProperty ($ reflectionTarget , 'parameters ' );
133
- $ reflectedParameters ->setAccessible (true );
134
- $ parameters = $ reflectedParameters ->getValue ($ reflectionTarget );
135
- unset($ parameters ['doctrine.connections ' ]);
136
- $ reflectedParameters ->setValue ($ reflectionTarget , $ parameters );
138
+ $ params = (array ) $ prop ->getValue ($ target );
139
+ unset($ params ['doctrine.connections ' ]);
140
+ $ prop ->setValue ($ target , $ params );
137
141
}
138
142
}
0 commit comments