From a3c93b25b287186aedc154b892d02faf66f72bed Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Tue, 5 Jul 2016 09:07:15 +0200 Subject: [PATCH] Added possibility for debug plugins (#22) * Added possibility for debug plugins * Added changelog * Style fixes * Added docs and corrected typos * typo * Validate debug_plugins option * Added tests to make sure the debug plugins runs between each plugin --- CHANGELOG.md | 1 + spec/PluginClientSpec.php | 42 +++++++++++++++++++++++++++++++++++++++ src/PluginClient.php | 28 ++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfdceab..5517c1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Added - Suggest separate plugins in composer.json +- Introduced `debug_plugins` option for `PluginClient` ## 1.1.0 - 2016-05-04 diff --git a/spec/PluginClientSpec.php b/spec/PluginClientSpec.php index 88406ae..27b4068 100644 --- a/spec/PluginClientSpec.php +++ b/spec/PluginClientSpec.php @@ -87,4 +87,46 @@ function it_throws_loop_exception(HttpClient $httpClient, RequestInterface $requ $this->shouldThrow('Http\Client\Common\Exception\LoopException')->duringSendRequest($request); } + + function it_injects_debug_plugins(HttpClient $httpClient, RequestInterface $request, Plugin $plugin0, Plugin $plugin1, Plugin $debugPlugin) + { + $plugin0 + ->handleRequest( + $request, + Argument::type('callable'), + Argument::type('callable') + ) + ->shouldBeCalledTimes(1) + ->will(function ($args) { + return $args[1]($args[0]); + }) + ; + $plugin1 + ->handleRequest( + $request, + Argument::type('callable'), + Argument::type('callable') + ) + ->shouldBeCalledTimes(1) + ->will(function ($args) { + return $args[1]($args[0]); + }) + ; + + $debugPlugin + ->handleRequest( + $request, + Argument::type('callable'), + Argument::type('callable') + ) + ->shouldBeCalledTimes(3) + ->will(function ($args) { + return $args[1]($args[0]); + }) + ; + + + $this->beConstructedWith($httpClient, [$plugin0, $plugin1], ['debug_plugins'=>[$debugPlugin]]); + $this->sendRequest($request); + } } diff --git a/src/PluginClient.php b/src/PluginClient.php index 9aa9e6c..2e69ecf 100644 --- a/src/PluginClient.php +++ b/src/PluginClient.php @@ -44,7 +44,8 @@ final class PluginClient implements HttpClient, HttpAsyncClient * @param Plugin[] $plugins * @param array $options { * - * @var int $max_restarts + * @var int $max_restarts + * @var Plugin[] $debug_plugins an array of plugins that are injected between each normal plugin * } * * @throws \RuntimeException if client is not an instance of HttpClient or HttpAsyncClient @@ -110,8 +111,22 @@ private function configure(array $options = []) $resolver = new OptionsResolver(); $resolver->setDefaults([ 'max_restarts' => 10, + 'debug_plugins' => [], ]); + $resolver + ->setAllowedTypes('debug_plugins', 'array') + ->setAllowedValues('debug_plugins', function (array $plugins) { + foreach ($plugins as $plugin) { + // Make sure each object passed with the `debug_plugins` is an instance of Plugin. + if (!$plugin instanceof Plugin) { + return false; + } + } + + return true; + }); + return $resolver->resolve($options); } @@ -127,7 +142,16 @@ private function createPluginChain($pluginList, callable $clientCallable) { $firstCallable = $lastCallable = $clientCallable; - while ($plugin = array_pop($pluginList)) { + /* + * Inject debug plugins between each plugin. + */ + $pluginListWithDebug = $this->options['debug_plugins']; + foreach ($pluginList as $plugin) { + $pluginListWithDebug[] = $plugin; + $pluginListWithDebug = array_merge($pluginListWithDebug, $this->options['debug_plugins']); + } + + while ($plugin = array_pop($pluginListWithDebug)) { $lastCallable = function (RequestInterface $request) use ($plugin, $lastCallable, &$firstCallable) { return $plugin->handleRequest($request, $lastCallable, $firstCallable); };