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