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