@@ -45,6 +45,46 @@ class FakeStream implements StreamInterface
4545 'stream_type ' => 'tcp_socket/unknown ' ,
4646 ];
4747
48+ /**
49+ * The failure to report once all queued responses have been read.
50+ */
51+ protected ?string $ failureWhenEmpty = null ;
52+
53+ /**
54+ * The most recently configured read timeout.
55+ */
56+ protected ?int $ timeout = null ;
57+
58+ /**
59+ * Simulate a disconnection after the queued responses are consumed.
60+ */
61+ public function disconnectWhenEmpty (): self
62+ {
63+ $ this ->failureWhenEmpty = 'eof ' ;
64+
65+ return $ this ;
66+ }
67+
68+ /**
69+ * Simulate a timeout after the queued responses are consumed.
70+ */
71+ public function timeoutWhenEmpty (): self
72+ {
73+ $ this ->failureWhenEmpty = 'timed_out ' ;
74+
75+ return $ this ;
76+ }
77+
78+ /**
79+ * Apply the scripted failure when there are no responses left to read.
80+ */
81+ protected function failWhenEmpty (): void
82+ {
83+ if (! $ this ->buffer && $ this ->failureWhenEmpty !== null ) {
84+ $ this ->meta [$ this ->failureWhenEmpty ] = true ;
85+ }
86+ }
87+
4888 /**
4989 * Feed a line to the stream buffer with a newline character.
5090 */
@@ -99,6 +139,8 @@ public function setMeta(string $attribute, mixed $value): self
99139 */
100140 public function open (?string $ transport = null , ?string $ host = null , ?int $ port = null , ?int $ timeout = null , array $ options = []): bool
101141 {
142+ $ this ->timeout = $ timeout ;
143+
102144 $ this ->connection = compact ('transport ' , 'host ' , 'port ' , 'timeout ' , 'options ' );
103145
104146 return true ;
@@ -122,8 +164,10 @@ public function read(int $length): string|false
122164 return false ;
123165 }
124166
125- if ($ this ->meta ['eof ' ] && empty ($ this ->buffer )) {
126- return false ; // EOF and no data left. Indicate end of stream.
167+ $ this ->failWhenEmpty ();
168+
169+ if ($ this ->meta ['timed_out ' ] || ($ this ->meta ['eof ' ] && empty ($ this ->buffer ))) {
170+ return false ;
127171 }
128172
129173 $ data = implode ('' , $ this ->buffer );
@@ -156,6 +200,8 @@ public function fgets(): string|false
156200 return false ;
157201 }
158202
203+ $ this ->failWhenEmpty ();
204+
159205 // Simulate timeout/eof checks.
160206 if ($ this ->meta ['timed_out ' ] || $ this ->meta ['eof ' ]) {
161207 return false ;
@@ -199,9 +245,19 @@ public function opened(): bool
199245 */
200246 public function setTimeout (int $ seconds ): bool
201247 {
248+ $ this ->timeout = $ seconds ;
249+
202250 return true ;
203251 }
204252
253+ /**
254+ * Get the most recently configured read timeout.
255+ */
256+ public function timeout (): ?int
257+ {
258+ return $ this ->timeout ;
259+ }
260+
205261 /**
206262 * {@inheritDoc}
207263 */
0 commit comments