88use Http \Client \HttpAsyncClient ;
99use Http \Client \HttpClient ;
1010use Http \Discovery \MessageFactoryDiscovery ;
11+ use Http \Message \RequestMatcher ;
1112use Http \Message \ResponseFactory ;
13+ use Psr \Http \Client \ClientExceptionInterface ;
1214use Psr \Http \Message \RequestInterface ;
1315use Psr \Http \Message \ResponseInterface ;
1416
@@ -30,6 +32,11 @@ class Client implements HttpClient, HttpAsyncClient
3032 */
3133 private $ responseFactory ;
3234
35+ /**
36+ * @var array
37+ */
38+ private $ conditionalResults = [];
39+
3340 /**
3441 * @var RequestInterface[]
3542 */
@@ -67,6 +74,22 @@ public function doSendRequest(RequestInterface $request)
6774 {
6875 $ this ->requests [] = $ request ;
6976
77+ foreach ($ this ->conditionalResults as $ result ) {
78+ /**
79+ * @var RequestMatcher
80+ */
81+ $ matcher = $ result ['matcher ' ];
82+
83+ /**
84+ * @var callable
85+ */
86+ $ callable = $ result ['callable ' ];
87+
88+ if ($ matcher ->matches ($ request )) {
89+ return $ callable ($ request );
90+ }
91+ }
92+
7093 if (count ($ this ->exceptions ) > 0 ) {
7194 throw array_shift ($ this ->exceptions );
7295 }
@@ -87,6 +110,46 @@ public function doSendRequest(RequestInterface $request)
87110 return $ this ->responseFactory ->createResponse ();
88111 }
89112
113+ /**
114+ * Adds an exception to be thrown or response to be returned if the request
115+ * matcher matches.
116+ *
117+ * For more complex logic, pass a callable as $result. The method is given
118+ * the request and MUST either return a ResponseInterface or throw an
119+ * exception that implements the PSR-18 / HTTPlug exception interface.
120+ *
121+ * @param ResponseInterface|Exception|ClientExceptionInterface|callable $result
122+ */
123+ public function on (RequestMatcher $ requestMatcher , $ result )
124+ {
125+ $ callable = null ;
126+
127+ switch (true ) {
128+ case is_callable ($ result ):
129+ $ callable = $ result ;
130+
131+ break ;
132+ case $ result instanceof ResponseInterface:
133+ $ callable = function () use ($ result ) {
134+ return $ result ;
135+ };
136+
137+ break ;
138+ case $ result instanceof \Exception:
139+ $ callable = function () use ($ result ) {
140+ throw $ result ;
141+ };
142+
143+ break ;
144+ default :
145+ throw new \InvalidArgumentException ('Result must be either a response, an exception, or a callable ' );
146+ }
147+ $ this ->conditionalResults [] = [
148+ 'matcher ' => $ requestMatcher ,
149+ 'callable ' => $ callable ,
150+ ];
151+ }
152+
90153 /**
91154 * Adds an exception that will be thrown.
92155 */
0 commit comments