diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da9c9a8..1e5c8c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,5 @@ name: Continuous Integration -on: [push] +on: [push, pull_request] jobs: linter: diff --git a/.gitignore b/.gitignore index c165836..7ce87f3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,5 @@ composer.lock bin ###> friendsofphp/php-cs-fixer ### -/.php_cs -/.php_cs.cache +/.php-cs-fixer.cache ###< friendsofphp/php-cs-fixer ### diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php similarity index 58% rename from .php_cs.dist rename to .php-cs-fixer.dist.php index 2988c2a..14f2738 100644 --- a/.php_cs.dist +++ b/.php-cs-fixer.dist.php @@ -1,10 +1,11 @@ getFinder() ->in( [ __DIR__.'/src', + __DIR__.'/tests', ] ); diff --git a/Makefile b/Makefile index c203847..db49bb8 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,9 @@ install: clean-vendor composer-install .PHONY: quality quality: cs-ci +.PHONY: quality-fix +quality-fix: cs-fix + .PHONY: test test: atoum @@ -59,4 +62,3 @@ ${SOURCE_DIR}/vendor/composer/installed.json: atoum: $(call printSection,TEST atoum) ${BIN_DIR}/atoum - diff --git a/README.md b/README.md index 69276da..960485d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # GuzzleHttpBundle -[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2FBedrockStreaming%2FGuzzleHttpBundle%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/BedrockStreaming/GuzzleHttpBundle/goto?ref=master) +[![Build Status](https://github.com/BedrockStreaming/GuzzleHttpBundle/actions/workflows/ci.yml/badge.svg)](https://github.com/BedrockStreaming/GuzzleHttpBundle/actions/workflows/ci.yml) [![Latest Stable Version](http://poser.pugx.org/m6web/guzzle-http-bundle/v)](https://packagist.org/packages/m6web/guzzle-http-bundle) [![Total Downloads](http://poser.pugx.org/m6web/guzzle-http-bundle/downloads)](https://packagist.org/packages/m6web/guzzle-http-bundle) [![License](http://poser.pugx.org/m6web/guzzle-http-bundle/license)](https://packagist.org/packages/m6web/guzzle-http-bundle) [![PHP Version Require](http://poser.pugx.org/m6web/guzzle-http-bundle/require/php)](https://packagist.org/packages/m6web/guzzle-http-bundle) The GuzzleHttpBundle provide a guzzle client as symfony service. diff --git a/composer.json b/composer.json index 97d718a..2a25a42 100644 --- a/composer.json +++ b/composer.json @@ -14,17 +14,17 @@ "require": { "php": ">=7.4", "ext-curl": "*", - "guzzlehttp/guzzle": "~6.3", - "symfony/config" : "~4.4||~5.0||~6.0", - "symfony/dependency-injection": "~4.4||~5.0||~6.0", - "symfony/event-dispatcher": "~4.4||~5.0||~6.0", - "symfony/http-kernel": "~4.4||~5.0||~6.0", - "symfony/yaml" : "~4.4||~5.0||~6.0" + "guzzlehttp/guzzle": "^6.3||^7.0", + "symfony/config" : "^4.4||^5.0||^6.0", + "symfony/dependency-injection": "^4.4||^5.0||^6.0", + "symfony/event-dispatcher": "^4.4||^5.0||^6.0", + "symfony/http-kernel": "^4.4||^5.0||^6.0", + "symfony/yaml" : "^4.4||^5.0||^6.0" }, "require-dev": { - "atoum/atoum": "~4.0", + "atoum/atoum": "4.0.3", "atoum/stubs": "*", - "m6web/php-cs-fixer-config": "^1.0" + "m6web/php-cs-fixer-config": "2.0.0" }, "autoload": { "psr-4": {"M6Web\\Bundle\\GuzzleHttpBundle\\": "src/"} diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 4a2897f..f6b0755 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -13,6 +13,7 @@ public function getConfigTreeBuilder(): TreeBuilder $treeBuilder->getRootNode() ->children() + ->booleanNode('clients_share_the_same_handler')->defaultTrue()->end() ->arrayNode('clients') ->isRequired() ->requiresAtLeastOneElement() diff --git a/src/DependencyInjection/M6WebGuzzleHttpExtension.php b/src/DependencyInjection/M6WebGuzzleHttpExtension.php index c7a207e..0d8135e 100644 --- a/src/DependencyInjection/M6WebGuzzleHttpExtension.php +++ b/src/DependencyInjection/M6WebGuzzleHttpExtension.php @@ -29,8 +29,12 @@ public function load(array $configs, ContainerBuilder $container) $isDebugEnabled = $container->getParameter('kernel.debug'); + if ($useSameHandler = $config['clients_share_the_same_handler']) { + $this->addGuzzleProxyHandlerAndHandlerStack($container, null, $config, $isDebugEnabled); + } + foreach ($config['clients'] as $clientId => $clientConfig) { - $this->loadClient($container, $clientId, $clientConfig, $isDebugEnabled); + $this->loadClient($container, $clientId, $clientConfig, $isDebugEnabled, $useSameHandler); } if ($isDebugEnabled) { @@ -44,11 +48,7 @@ public function getAlias(): string return 'm6web_guzzlehttp'; } - /** - * @param string $clientId - * @param bool $isDebugEnabled - */ - protected function loadClient(ContainerBuilder $container, $clientId, array $config, $isDebugEnabled) + protected function loadClient(ContainerBuilder $container, string $clientId, array $config, bool $isDebugEnabled, bool $useSameHandler) { // clear empty arrays foreach ($config as $key => $item) { @@ -60,17 +60,14 @@ protected function loadClient(ContainerBuilder $container, $clientId, array $con if ($config['allow_redirects']['max'] == 0) { $config['allow_redirects'] = false; } + if ($useSameHandler) { + $container->setAlias($this->buildGuzzleProxyHandlerServiceName($clientId), $this->buildGuzzleProxyHandlerServiceName(null))->setPublic(true); + $container->setAlias($this->buildGuzzleHandlerStackServiceName($clientId), $this->buildGuzzleHandlerStackServiceName(null))->setPublic(true); + } else { + $this->addGuzzleProxyHandlerAndHandlerStack($container, $clientId, $config, $isDebugEnabled); + } - $this->setGuzzleProxyHandler($container, $clientId, $config, $isDebugEnabled); - - $handlerStackDefinition = new Definition('%m6web_guzzlehttp.guzzle.handlerstack.class%'); - $handlerStackDefinition->setPublic(true); - $handlerStackDefinition->setFactory(['%m6web_guzzlehttp.guzzle.handlerstack.class%', 'create']); - $handlerStackDefinition->setArguments([new Reference('m6web_guzzlehttp.guzzle.proxyhandler_'.$clientId)]); - - $container->setDefinition('m6web_guzzlehttp.guzzle.handlerstack.'.$clientId, $handlerStackDefinition); - - $handlerStackReference = new Reference('m6web_guzzlehttp.guzzle.handlerstack.'.$clientId); + $handlerStackReference = new Reference($this->buildGuzzleHandlerStackServiceName($clientId)); $middlewareEventDispatcherDefinition = new Definition('%m6web_guzzlehttp.middleware.eventdispatcher.class%'); $middlewareEventDispatcherDefinition->setPublic(true); @@ -132,13 +129,22 @@ protected function loadClient(ContainerBuilder $container, $clientId, array $con $container->setDefinition($containerKey, $guzzleClientDefinition); } + private function addGuzzleProxyHandlerAndHandlerStack(ContainerBuilder $container, ?string $clientId, array $config, bool $isDebugEnabled): void + { + $this->setGuzzleProxyHandler($container, $clientId, $config, $isDebugEnabled); + $handlerStackDefinition = new Definition('%m6web_guzzlehttp.guzzle.handlerstack.class%'); + + $handlerStackDefinition->setPublic(true); + $handlerStackDefinition->setFactory(['%m6web_guzzlehttp.guzzle.handlerstack.class%', 'create']); + $handlerStackDefinition->setArguments([new Reference($this->buildGuzzleProxyHandlerServiceName($clientId))]); + + $container->setDefinition($this->buildGuzzleHandlerStackServiceName($clientId), $handlerStackDefinition); + } + /** * Set proxy handler definition for the client - * - * @param string $clientId - * @param bool $isDebugEnabled */ - protected function setGuzzleProxyHandler(ContainerBuilder $container, $clientId, array $config, $isDebugEnabled) + protected function setGuzzleProxyHandler(ContainerBuilder $container, ?string $clientId, array $config, bool $isDebugEnabled) { // arguments (3 and 50) in handler factories below represents the maximum number of idle handles. // the values are the default defined in guzzle CurlHandler and CurlMultiHandler @@ -161,7 +167,10 @@ protected function setGuzzleProxyHandler(ContainerBuilder $container, $clientId, $curlMultiHandler->addMethodCall('setDebug', [$isDebugEnabled]); if (isset($config['guzzlehttp_cache'])) { - if (is_null($cacheService = $this->getServiceReference($config['guzzlehttp_cache']['service']))) { + if ( + !isset($config['guzzlehttp_cache']['service']) + || is_null($cacheService = $this->getServiceReference($config['guzzlehttp_cache']['service'])) + ) { throw new \InvalidArgumentException(sprintf('"guzzlehttp_cache.service" requires a valid service reference, "%s" given', $config['guzzlehttp_cache']['service'])); } @@ -180,7 +189,7 @@ protected function setGuzzleProxyHandler(ContainerBuilder $container, $clientId, $proxyHandler->setFactory(['%m6web_guzzlehttp.guzzle.proxyhandler.class%', 'wrapSync']); $proxyHandler->setArguments([$curlMultiHandler, $curlHandler]); - $container->setDefinition('m6web_guzzlehttp.guzzle.proxyhandler_'.$clientId, $proxyHandler); + $container->setDefinition($this->buildGuzzleProxyHandlerServiceName($clientId), $proxyHandler); } protected function getCurlConfig(array $config) @@ -221,7 +230,7 @@ protected function getCurlConfig(array $config) return $curlInfo; } - protected function getServiceReference($id) + protected function getServiceReference(string $id) { if (substr($id, 0, 1) == '@') { return new Reference(substr($id, 1)); @@ -268,4 +277,20 @@ protected function parseHeaders(array $headers) return $newHeaders; } + + private function buildGuzzleProxyHandlerServiceName(?string $clientId): string + { + return sprintf( + 'm6web_guzzlehttp.guzzle.proxyhandler%s', + !empty($clientId) ? '_'.$clientId : '' + ); + } + + private function buildGuzzleHandlerStackServiceName(?string $clientId): string + { + return sprintf( + 'm6web_guzzlehttp.guzzle.handlerstack%s', + !empty($clientId) ? '.'.$clientId : '' + ); + } } diff --git a/src/EventDispatcher/AbstractGuzzleCacheEvent.php b/src/EventDispatcher/AbstractGuzzleCacheEvent.php index 352f493..8b21304 100644 --- a/src/EventDispatcher/AbstractGuzzleCacheEvent.php +++ b/src/EventDispatcher/AbstractGuzzleCacheEvent.php @@ -11,10 +11,10 @@ abstract class AbstractGuzzleCacheEvent extends Event { /** @const string Name of standard event */ - const NAME = 'm6web.guzzlecache'; + public const NAME = 'm6web.guzzlecache'; /** @const string Name of Error event */ - const NAME_ERROR = 'm6web.guzzlecache.error'; + public const NAME_ERROR = 'm6web.guzzlecache.error'; /** @var RequestInterface */ protected $request; diff --git a/src/EventDispatcher/AbstractGuzzleHttpEvent.php b/src/EventDispatcher/AbstractGuzzleHttpEvent.php index 115a5d6..d77ff7f 100644 --- a/src/EventDispatcher/AbstractGuzzleHttpEvent.php +++ b/src/EventDispatcher/AbstractGuzzleHttpEvent.php @@ -13,8 +13,8 @@ */ abstract class AbstractGuzzleHttpEvent extends Event { - const EVENT_NAME = 'm6web.guzzlehttp'; - const EVENT_ERROR_NAME = 'm6web.guzzlehttp.error'; + public const EVENT_NAME = 'm6web.guzzlehttp'; + public const EVENT_ERROR_NAME = 'm6web.guzzlehttp.error'; /** @var float Command start time */ protected $executionStart; diff --git a/src/Handler/CacheTrait.php b/src/Handler/CacheTrait.php index a88d31a..725eaa2 100644 --- a/src/Handler/CacheTrait.php +++ b/src/Handler/CacheTrait.php @@ -3,6 +3,7 @@ namespace M6Web\Bundle\GuzzleHttpBundle\Handler; use GuzzleHttp\Promise\FulfilledPromise; +use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Psr7\Response; use M6Web\Bundle\GuzzleHttpBundle\Cache\CacheInterface; use M6Web\Bundle\GuzzleHttpBundle\EventDispatcher\GuzzleCacheErrorEvent; @@ -188,17 +189,15 @@ protected function getCached(RequestInterface $request) * Check if request is in cache and return the response in this case * otherwise send request then cache the response * - * @return FulfilledPromise - * * @throws \Exception */ - public function __invoke(RequestInterface $request, array $options) + public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (is_null($this->cache)) { return parent::__invoke($request, $options); } - //user want to force cache reload + // user want to force cache reload // so we remove existing cache if (array_key_exists('cache_force', $options)) { $this->cache->remove(self::getKey($request)); @@ -223,7 +222,7 @@ public function __invoke(RequestInterface $request, array $options) $result = parent::__invoke($request, $options); // then ask promise to cache the response when she's resolved $result->then(function (ResponseInterface $response) use ($request, $options) { - //check if user want a specific cache duration + // check if user want a specific cache duration $ttl = (!empty($options['cache_ttl'])) ? $options['cache_ttl'] : null; $this->cacheResponse($request, $response, $ttl); diff --git a/src/Handler/CurlFactory.php b/src/Handler/CurlFactory.php index 2b75991..1734d6b 100644 --- a/src/Handler/CurlFactory.php +++ b/src/Handler/CurlFactory.php @@ -14,12 +14,12 @@ class CurlFactory extends GuzzleCurlFactory /** * {@inheritdoc} */ - public function release(EasyHandle $easy) + public function release(EasyHandle $easy): void { if (!is_null($easy->response)) { $easy->response->curlInfo = curl_getinfo($easy->handle); } - return parent::release($easy); + parent::release($easy); } } diff --git a/tests/Fixtures/cache-config-no-server-errors.yml b/tests/Fixtures/cache-config-no-server-errors.yml index 26c822c..9ba10c8 100644 --- a/tests/Fixtures/cache-config-no-server-errors.yml +++ b/tests/Fixtures/cache-config-no-server-errors.yml @@ -1,4 +1,5 @@ m6web_guzzlehttp: + clients_share_the_same_handler: false clients: default: base_uri: "http://domain.tld" diff --git a/tests/Fixtures/cache-config.yml b/tests/Fixtures/cache-config.yml index 6c2ea24..b707218 100644 --- a/tests/Fixtures/cache-config.yml +++ b/tests/Fixtures/cache-config.yml @@ -1,4 +1,5 @@ m6web_guzzlehttp: + clients_share_the_same_handler: false clients: default: base_uri: "http://domain.tld" diff --git a/tests/Fixtures/multiclient-config.yml b/tests/Fixtures/multiclient-config.yml index 9bec9f1..66a8b4a 100644 --- a/tests/Fixtures/multiclient-config.yml +++ b/tests/Fixtures/multiclient-config.yml @@ -1,4 +1,5 @@ m6web_guzzlehttp: + clients_share_the_same_handler: false clients: default: base_uri: "http://domain.tld" diff --git a/tests/Fixtures/multiclient-samehandler-config.yml b/tests/Fixtures/multiclient-samehandler-config.yml new file mode 100644 index 0000000..2f54703 --- /dev/null +++ b/tests/Fixtures/multiclient-samehandler-config.yml @@ -0,0 +1,13 @@ +m6web_guzzlehttp: + clients_share_the_same_handler: true + clients: + default: + base_uri: "http://domain.tld" + timeout: 2 + connect_timeout: 8 + read_timeout: 12 + allow_redirects: false + myclient: + base_uri: "http://domain2.tld" + headers: + User_Agent: "Towel/1.0" diff --git a/tests/Units/Cache/InMemory.php b/tests/Units/Cache/InMemory.php index 8ad855d..dfebfe2 100644 --- a/tests/Units/Cache/InMemory.php +++ b/tests/Units/Cache/InMemory.php @@ -2,9 +2,7 @@ namespace M6Web\Bundle\GuzzleHttpBundle\tests\Units\Cache; -use atoum; - -class InMemory extends atoum +class InMemory extends \atoum { public function testEmptyCache() { diff --git a/tests/Units/DependencyInjection/M6WebGuzzleHttpExtension.php b/tests/Units/DependencyInjection/M6WebGuzzleHttpExtension.php index 5636ef9..483fdbf 100644 --- a/tests/Units/DependencyInjection/M6WebGuzzleHttpExtension.php +++ b/tests/Units/DependencyInjection/M6WebGuzzleHttpExtension.php @@ -2,7 +2,6 @@ namespace M6Web\Bundle\GuzzleHttpBundle\tests\Units\DependencyInjection; -use atoum; use GuzzleHttp\Promise; use GuzzleHttp\Psr7\Response; use M6Web\Bundle\GuzzleHttpBundle\DependencyInjection\M6WebGuzzleHttpExtension as TestedClass; @@ -11,7 +10,7 @@ use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; -class M6WebGuzzleHttpExtension extends atoum +class M6WebGuzzleHttpExtension extends \atoum { public function testDefaultConfig() { @@ -142,6 +141,64 @@ public function testTimeoutConfig() ; } + public function testMultiClientSameHandlerConfig() + { + $container = $this->getContainerForConfiguration('multiclient-samehandler-config'); + $container->compile(); + + $this + ->boolean($container->has('m6web_guzzlehttp')) + ->isTrue() + ->array($arguments = $container->getDefinition('m6web_guzzlehttp')->getArgument(0)) + ->hasSize(10) + ->string($arguments['base_uri']) + ->isEqualTo('http://domain.tld') + ->integer($arguments['timeout']) + ->isEqualTo(2) + ->integer($arguments['connect_timeout']) + ->isEqualTo(8) + ->integer($arguments['read_timeout']) + ->isEqualTo(12) + ->boolean($arguments['http_errors']) + ->isTrue() + ->boolean($arguments['allow_redirects']) + ->isFalse() + ->boolean($container->has('m6web_guzzlehttp.guzzle.handlerstack.default')) + ->isTrue() + ->boolean($container->has('m6web_guzzlehttp_myclient')) + ->isTrue() + ->array($arguments = $container->getDefinition('m6web_guzzlehttp_myclient')->getArgument(0)) + ->hasSize(11) + ->string($arguments['base_uri']) + ->isEqualTo('http://domain2.tld') + ->float($arguments['timeout']) + ->isEqualTo(5.0) + ->float($arguments['connect_timeout']) + ->isEqualTo(5.0) + ->float($arguments['read_timeout']) + ->isEqualTo(5.0) + ->array($redirect = $arguments['allow_redirects']) + ->hasSize(4) + ->hasKeys(['max', 'strict', 'referer', 'protocols']) + ->integer($redirect['max']) + ->isEqualTo(5) + ->boolean($redirect['strict']) + ->isFalse() + ->boolean($redirect['referer']) + ->isTrue() + ->array($redirect['protocols']) + ->hasSize(2) + ->isEqualTo(['http', 'https']) + ->array($headers = $arguments['headers']) + ->hasSize(1) + ->hasKey('User-Agent') + ->boolean($container->has('m6web_guzzlehttp.guzzle.handlerstack.myclient')) + ->isTrue() + ->object($container->get('m6web_guzzlehttp.guzzle.handlerstack.myclient')) + ->isIdenticalTo($container->get('m6web_guzzlehttp.guzzle.handlerstack.default')) + ; + } + public function testMultiClientConfig() { $container = $this->getContainerForConfiguration('multiclient-config'); @@ -164,6 +221,8 @@ public function testMultiClientConfig() ->isTrue() ->boolean($arguments['allow_redirects']) ->isFalse() + ->boolean($container->has('m6web_guzzlehttp.guzzle.handlerstack.default')) + ->isTrue() ->boolean($container->has('m6web_guzzlehttp_myclient')) ->isTrue() ->array($arguments = $container->getDefinition('m6web_guzzlehttp_myclient')->getArgument(0)) @@ -191,6 +250,10 @@ public function testMultiClientConfig() ->array($headers = $arguments['headers']) ->hasSize(1) ->hasKey('User-Agent') + ->boolean($container->has('m6web_guzzlehttp.guzzle.handlerstack.myclient')) + ->isTrue() + ->object($container->get('m6web_guzzlehttp.guzzle.handlerstack.myclient')) + ->isNotIdenticalTo($container->get('m6web_guzzlehttp.guzzle.handlerstack.default')) ; } @@ -427,7 +490,7 @@ protected function getSerializedResponse(Response $response) public function testRequestConfig() { $container = $this->getContainerBuilder(); - $container->set('invokable.service.id', new \StdClass()); + $container->set('invokable.service.id', new \stdClass()); $container = $this->getContainerForConfiguration('request-config', $container); $container->compile(); @@ -544,7 +607,7 @@ protected function getContainerForConfiguration($fixtureName, ContainerBuilder $ } $mockDispatcher = new \mock\Symfony\Component\EventDispatcher\EventDispatcherInterface(); - $mockDispatcher->getMockController()->dispatch = function($event) { + $mockDispatcher->getMockController()->dispatch = function ($event) { return $event; }; $container->set('event_dispatcher', $mockDispatcher); diff --git a/tests/Units/Handler/CurlMultiHandler.php b/tests/Units/Handler/CurlMultiHandler.php index 402be34..8f4a7ca 100644 --- a/tests/Units/Handler/CurlMultiHandler.php +++ b/tests/Units/Handler/CurlMultiHandler.php @@ -2,7 +2,6 @@ namespace M6Web\Bundle\GuzzleHttpBundle\tests\Units\Handler; -use atoum; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use M6Web\Bundle\GuzzleHttpBundle\Handler\CurlMultiHandler as TestedClass; @@ -13,7 +12,7 @@ * Class CurlMultiHandler * Used for testing trait and curlFactory */ -class CurlMultiHandler extends atoum +class CurlMultiHandler extends \atoum { public function testNoCache() { diff --git a/tests/Units/Middleware/EventDispatcherMiddleware.php b/tests/Units/Middleware/EventDispatcherMiddleware.php index 1c2f37e..e4c20d4 100644 --- a/tests/Units/Middleware/EventDispatcherMiddleware.php +++ b/tests/Units/Middleware/EventDispatcherMiddleware.php @@ -1,7 +1,7 @@ getMockController()->dispatch = function($event, $name) use (&$eventSend) { + $dispatcherMock->getMockController()->dispatch = function ($event, $name) use (&$eventSend) { $eventSend = $event; + return $event; }; // Mock HandlerStack $eventCallable = null; $handlerStackMock = new \mock\GuzzleHttp\HandlerStack(); - $handlerStackMock->getMockController()->push = function($callable, $str) use (&$eventCallable) { - if ($str == "eventDispatcher_dispatch") { + $handlerStackMock->getMockController()->push = function ($callable, $str) use (&$eventCallable) { + if ($str == 'eventDispatcher_dispatch') { $eventCallable = $callable; } }; // Response & request - $requestMock = new \mock\Psr\Http\Message\RequestInterface(); + $requestMock = new \mock\Psr\Http\Message\RequestInterface(); $responseMock = new \mock\Psr\Http\Message\ResponseInterface(); // Mock guzzle promise $successCallable = null; - $errorCallable = null; + $errorCallable = null; $promiseMock = new \mock\GuzzleHttp\Promise(); - $promiseMock->getMockController()->then = function($success, $error) use (&$successCallable, &$errorCallable) { + $promiseMock->getMockController()->then = function ($success, $error) use (&$successCallable, &$errorCallable) { $successCallable = $success; - $errorCallable = $error; + $errorCallable = $error; }; // Handler for end of event - $handlerEvent = function() use( $promiseMock) { + $handlerEvent = function () use ($promiseMock) { return $promiseMock; }; @@ -93,8 +94,8 @@ public function testPush() ->object($errorCallable) ->isCallable() ->exception( - function() use ($errorCallable) { - $errorCallable(new \Exception("connexion error")); + function () use ($errorCallable) { + $errorCallable(new \Exception('connexion error')); } ) ->hasMessage('connexion error')