22namespace ScriptFUSIONTest \Integration \Porter \Connector ;
33
44use ScriptFUSION \Porter \Connector \ConnectionContext ;
5+ use ScriptFUSION \Porter \Connector \FetchExceptionHandler \StatelessFetchExceptionHandler ;
56use ScriptFUSION \Porter \Connector \RecoverableConnectorException ;
67use ScriptFUSIONTest \FixtureFactory ;
78use ScriptFUSIONTest \Stubs \TestFetchExceptionHandler ;
89
10+ /**
11+ * @see ConnectionContext
12+ */
913final class ConnectionContextTest extends \PHPUnit_Framework_TestCase
1014{
1115 /**
@@ -20,13 +24,7 @@ public function testFetchExceptionHandlerCloned(TestFetchExceptionHandler $handl
2024 $ handler ->initialize ();
2125 $ initial = $ handler ->getCurrent ();
2226
23- $ context ->retry (static function () {
24- static $ invocationCount ;
25-
26- if (!$ invocationCount ++) {
27- throw new RecoverableConnectorException ;
28- }
29- });
27+ $ context ->retry (self ::createExceptionThrowingClosure ());
3028
3129 self ::assertSame ($ initial , $ handler ->getCurrent ());
3230 }
@@ -43,4 +41,49 @@ public function provideHandlerAndContext()
4341 $ context ->setResourceFetchExceptionHandler ($ handler );
4442 yield 'Resource exception handler ' => [$ handler , $ context ];
4543 }
44+
45+ /**
46+ * Tests that when retry() is called, a stateless fetch exception handler is neither cloned nor reinitialized.
47+ * For stateless handlers, initialization is a NOOP, so avoiding cloning is a small optimization.
48+ */
49+ public function testStatelessExceptionHandlerNotCloned ()
50+ {
51+ $ context = FixtureFactory::buildConnectionContext (
52+ false ,
53+ $ handler = new StatelessFetchExceptionHandler (static function () {
54+ // Intentionally empty.
55+ })
56+ );
57+
58+ $ context ->retry (self ::createExceptionThrowingClosure ());
59+
60+ self ::assertSame (
61+ $ handler ,
62+ call_user_func (
63+ \Closure::bind (
64+ function () {
65+ return $ this ->fetchExceptionHandler ;
66+ },
67+ $ context ,
68+ $ context
69+ )
70+ )
71+ );
72+ }
73+
74+ /**
75+ * Creates a closure that only throws an exception on the first invocation.
76+ *
77+ * @return \Closure
78+ */
79+ private static function createExceptionThrowingClosure ()
80+ {
81+ return static function () {
82+ static $ invocationCount ;
83+
84+ if (!$ invocationCount ++) {
85+ throw new RecoverableConnectorException ;
86+ }
87+ };
88+ }
4689}
0 commit comments