From 19b9c7e7e37bf4beeec715f73b089a60e652e5ed Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Mon, 8 Dec 2025 09:46:41 +0100 Subject: [PATCH 1/8] test with symfony 8 --- .github/workflows/continuous-integration.yml | 4 +++ CHANGELOG.md | 4 ++- composer.json | 26 ++++++++++---------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index a387e736..f773fe8d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -72,6 +72,10 @@ jobs: symfony-require: "7.4.*" php-version: "8.5" symfony-deprecations-helper: "weak" + - dependencies: "php-http/guzzle7-adapter symfony/http-client:^8" + symfony-require: "8.0.*" + php-version: "8.5" + symfony-deprecations-helper: "weak" steps: - name: "Checkout" diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f82761b..9f5e5801 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee # Version 2 -# 2.2.0 - 2025-12-08 +# 2.2.0 - unreleased + +- Compatible with Symfony 8. - Replaced XML configuration with PHP configuration. # 2.1.0 - 2024-11-24 diff --git a/composer.json b/composer.json index 7d89d691..e0e06092 100644 --- a/composer.json +++ b/composer.json @@ -35,11 +35,11 @@ "php-http/stopwatch-plugin": "^1.2", "psr/http-factory-implementation": "^1.0", "psr/http-message": "^1.0 || ^2.0", - "symfony/config": "^6.4 || ^7.1", - "symfony/dependency-injection": "^6.4 || ^7.1", - "symfony/event-dispatcher": "^6.4 || ^7.1", - "symfony/http-kernel": "^6.4 || ^7.1", - "symfony/options-resolver": "^6.4 || ^7.1" + "symfony/config": "^6.4 || ^7.1 || ^8.0", + "symfony/dependency-injection": "^6.4 || ^7.1 || ^8.0", + "symfony/event-dispatcher": "^6.4 || ^7.1 || ^8.0", + "symfony/http-kernel": "^6.4 || ^7.1 || ^8.0", + "symfony/options-resolver": "^6.4 || ^7.1 || ^8.0" }, "conflict": { "kriswallsmith/buzz": "<0.17", @@ -61,14 +61,14 @@ "php-http/promise": "^1.0", "php-http/throttle-plugin": "^1.1", "phpunit/phpunit": "^9", - "symfony/browser-kit": "^6.4 || ^7.1", - "symfony/cache": "^6.4 || ^7.1", - "symfony/dom-crawler": "^6.4 || ^7.1", - "symfony/framework-bundle": "^6.4 || ^7.1", - "symfony/http-foundation": "^6.4 || ^7.1", - "symfony/stopwatch": "^6.4 || ^7.1", - "symfony/twig-bundle": "^6.4 || ^7.1", - "symfony/web-profiler-bundle": "^6.4 || ^7.1", + "symfony/browser-kit": "^6.4 || ^7.1 || ^8.0", + "symfony/cache": "^6.4 || ^7.1 || ^8.0", + "symfony/dom-crawler": "^6.4 || ^7.1 || ^8.0", + "symfony/framework-bundle": "^6.4 || ^7.1 || ^8.0", + "symfony/http-foundation": "^6.4 || ^7.1 || ^8.0", + "symfony/stopwatch": "^6.4 || ^7.1 || ^8.0", + "symfony/twig-bundle": "^6.4 || ^7.1 || ^8.0", + "symfony/web-profiler-bundle": "^6.4 || ^7.1 || ^8.0", "twig/twig": "^1.41 || ^2.10 || ^3.0" }, "suggest": { From d577690050d4436b99903d6eba2f295d5876c305 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Tue, 9 Dec 2025 11:09:55 +0100 Subject: [PATCH 2/8] fix stability handling and workaround for symfony 8 bug --- .github/workflows/continuous-integration.yml | 11 +++++++++-- composer.json | 7 +++---- tests/Functional/DiscoveredClientsTest.php | 3 ++- tests/Functional/Issue206.php | 3 +-- tests/Functional/ProfilerTest.php | 2 ++ tests/Functional/ProfilingTest.php | 2 +- tests/Functional/ServiceInstantiationTest.php | 2 ++ tests/Unit/Collector/FormatterTest.php | 2 ++ .../Unit/DependencyInjection/HttplugExtensionTest.php | 7 ++++++- 9 files changed, 28 insertions(+), 11 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f773fe8d..3f966ffc 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -92,14 +92,21 @@ jobs: tools: "flex" - name: "Enforce using stable dependencies" - run: "composer config minimum-stability stable" - if: "${{ matrix.stability == 'stable' }}" + run: "composer config minimum-stability ${{ matrix.stability }}" + if: "${{ matrix.stability }}" - name: "Add dependencies and enable flex" run: | composer config allow-plugins.symfony/flex true composer require --no-update ${{ matrix.dependencies }} + - name: "Work around https://github.com/symfony/symfony/pull/62692" + run: "composer require --no-update symfony/console:*" + + - name: "Get correct version for workaround" + run: "composer require --no-update symfony/console:${{ matrix.symfony-require }}" + if: "${{ matrix.symfony-require }}" + - name: "Install dependencies with Composer" uses: "ramsey/composer-install@v3" with: diff --git a/composer.json b/composer.json index e0e06092..7b32389f 100644 --- a/composer.json +++ b/composer.json @@ -52,15 +52,15 @@ }, "require-dev": { "guzzlehttp/psr7": "^1.7 || ^2.0", - "matthiasnoback/symfony-config-test": "^5.2", - "matthiasnoback/symfony-dependency-injection-test": "^4.3.1 || ^5.0", + "matthiasnoback/symfony-config-test": "^5.2 || ^v6.1.0", + "matthiasnoback/symfony-dependency-injection-test": "^4.3.1 || ^5.0 || ^6.2.0", "nyholm/nsa": "^1.1", "nyholm/psr7": "^1.2.1", "php-http/cache-plugin": "^1.7", "php-http/mock-client": "^1.2", "php-http/promise": "^1.0", "php-http/throttle-plugin": "^1.1", - "phpunit/phpunit": "^9", + "phpunit/phpunit": "^9 || ^10.0 || ^11.0 || ^12.0", "symfony/browser-kit": "^6.4 || ^7.1 || ^8.0", "symfony/cache": "^6.4 || ^7.1 || ^8.0", "symfony/dom-crawler": "^6.4 || ^7.1 || ^8.0", @@ -96,7 +96,6 @@ "tests/Resources/app/AppKernel.php" ] }, - "prefer-stable": false, "scripts": { "test": "vendor/bin/phpunit", "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml" diff --git a/tests/Functional/DiscoveredClientsTest.php b/tests/Functional/DiscoveredClientsTest.php index d93ca3f3..5f852b51 100644 --- a/tests/Functional/DiscoveredClientsTest.php +++ b/tests/Functional/DiscoveredClientsTest.php @@ -15,6 +15,7 @@ use Nyholm\NSA; use Psr\Http\Client\ClientInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use Symfony\Component\DependencyInjection\ContainerInterface; final class DiscoveredClientsTest extends WebTestCase { @@ -119,7 +120,7 @@ public function testForcedDiscovery(): void $this->assertEquals($container->get('httplug.client.acme'), HttpAsyncClientDiscovery::find()); } - private function getCustomContainer($debug, $environment = 'test') + private function getCustomContainer($debug, $environment = 'test'): ContainerInterface { static::bootKernel(['debug' => $debug, 'environment' => $environment]); diff --git a/tests/Functional/Issue206.php b/tests/Functional/Issue206.php index 852d68af..9ba2c852 100644 --- a/tests/Functional/Issue206.php +++ b/tests/Functional/Issue206.php @@ -5,7 +5,6 @@ namespace Http\HttplugBundle\Tests\Functional; use Http\Client\Common\HttpMethodsClient; -use Http\Client\Common\PluginClient; use Http\Client\Common\PluginClientFactory; use Http\Discovery\Psr18ClientDiscovery; use Nyholm\Psr7\Factory\Psr17Factory; @@ -24,6 +23,6 @@ public function testCustomClientDoesNotCauseException(): void $pluginClient = (new PluginClientFactory())->createClient($myCustomClient, []); // If we get to this line, no exceptions has been thrown. - $this->assertInstanceOf(PluginClient::class, $pluginClient); + $this->addToAssertionCount(1); } } diff --git a/tests/Functional/ProfilerTest.php b/tests/Functional/ProfilerTest.php index 3654f4a3..bd283187 100644 --- a/tests/Functional/ProfilerTest.php +++ b/tests/Functional/ProfilerTest.php @@ -5,6 +5,7 @@ namespace Http\HttplugBundle\Tests\Functional; use GuzzleHttp\Psr7\Request; +use PHPUnit\Framework\Attributes\Group; use Psr\Http\Client\ClientInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; @@ -13,6 +14,7 @@ final class ProfilerTest extends WebTestCase /** * @group legacy */ + #[Group('legacy')] public function testShowProfiler(): void { $client = static::createClient(); diff --git a/tests/Functional/ProfilingTest.php b/tests/Functional/ProfilingTest.php index f9aed161..4ade5ea9 100644 --- a/tests/Functional/ProfilingTest.php +++ b/tests/Functional/ProfilingTest.php @@ -95,7 +95,7 @@ public function testProfiling(): void $this->assertEquals('example.com', $stack->getRequestHost()); } - private function createClient(array $plugins, $clientName = 'Acme', array $clientOptions = []) + private function createClient(array $plugins, string $clientName = 'Acme', array $clientOptions = []) { $plugins = array_map(fn (Plugin $plugin) => new ProfilePlugin($plugin, $this->collector, $this->formatter, $plugin::class), $plugins); diff --git a/tests/Functional/ServiceInstantiationTest.php b/tests/Functional/ServiceInstantiationTest.php index 16bc2e2e..327f37c6 100644 --- a/tests/Functional/ServiceInstantiationTest.php +++ b/tests/Functional/ServiceInstantiationTest.php @@ -13,6 +13,7 @@ use Http\HttplugBundle\Collector\ProfilePlugin; use Http\HttplugBundle\Collector\StackPlugin; use Nyholm\NSA; +use PHPUnit\Framework\Attributes\Group; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\ResponseInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; @@ -55,6 +56,7 @@ public function testHttpClientNoDebug(): void /** * @group legacy */ + #[Group('legacy')] public function testDebugToolbar(): void { static::bootKernel(['debug' => true]); diff --git a/tests/Unit/Collector/FormatterTest.php b/tests/Unit/Collector/FormatterTest.php index 3b2aaddc..78ec0dfd 100644 --- a/tests/Unit/Collector/FormatterTest.php +++ b/tests/Unit/Collector/FormatterTest.php @@ -12,6 +12,7 @@ use Http\Message\Formatter as MessageFormatter; use Http\Message\Formatter\CurlCommandFormatter; use Http\Message\Formatter\SimpleFormatter; +use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -66,6 +67,7 @@ public function testFormatResponseForRequest(): void /** * @group legacy */ + #[Group('legacy')] public function testFormatResponse(): void { $response = new Response(); diff --git a/tests/Unit/DependencyInjection/HttplugExtensionTest.php b/tests/Unit/DependencyInjection/HttplugExtensionTest.php index a1c51a24..4db47a9c 100644 --- a/tests/Unit/DependencyInjection/HttplugExtensionTest.php +++ b/tests/Unit/DependencyInjection/HttplugExtensionTest.php @@ -9,6 +9,8 @@ use Http\HttplugBundle\DependencyInjection\HttplugExtension; use Http\HttplugBundle\Tests\Resources\CustomPluginConfigurator; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Group; use Psr\Http\Client\ClientInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; @@ -505,6 +507,8 @@ public function testClientIsTaggedWithHttplugClientTag(): void * * @group vcr-plugin */ + #[DataProvider('provideVcrPluginConfig')] + #[Group('vcr-plugin')] public function testVcrPluginConfiguration(array $config, array $services, array $arguments = []): void { if (!class_exists(InMemoryRecorder::class)) { @@ -529,6 +533,7 @@ public function testVcrPluginConfiguration(array $config, array $services, array /** * @group vcr-plugin */ + #[Group('vcr-plugin')] public function testIsNotLoadedUnlessNeeded(): void { if (!class_exists(InMemoryRecorder::class)) { @@ -539,7 +544,7 @@ public function testIsNotLoadedUnlessNeeded(): void $this->assertContainerBuilderNotHasService('httplug.plugin.vcr.recorder.in_memory'); } - public function provideVcrPluginConfig() + public static function provideVcrPluginConfig(): \Generator { $config = [ 'mode' => 'record', From 356815c295be74a28edbb6bcb85e3c9c2a1020fe Mon Sep 17 00:00:00 2001 From: Orest Divintari Date: Fri, 19 Dec 2025 21:22:33 +0200 Subject: [PATCH 3/8] Fix Collector uninitialized property --- src/Collector/Collector.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Collector/Collector.php b/src/Collector/Collector.php index 89a23d04..fcd6a680 100644 --- a/src/Collector/Collector.php +++ b/src/Collector/Collector.php @@ -22,9 +22,11 @@ final class Collector extends DataCollector { private ?Stack $activeStack = null; + private ?int $capturedBodyLength = null; - public function __construct(private ?int $capturedBodyLength = null) + public function __construct(?int $capturedBodyLength = null) { + $this->capturedBodyLength = $capturedBodyLength; $this->reset(); } From 87436116019b556610aa43bc8919d0bb69e1b520 Mon Sep 17 00:00:00 2001 From: Orest Divintari Date: Fri, 19 Dec 2025 21:22:46 +0200 Subject: [PATCH 4/8] Fix XML loader errors for Symfony 8 --- .../Unit/DependencyInjection/ConfigurationTest.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index 6ba3d3a4..e85477bf 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -13,6 +13,8 @@ use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\HttpKernel\Kernel; +use function class_exists; /** * @author David Buchmann @@ -322,11 +324,17 @@ public function testSupportsAllConfigFormats(): void ], ]; - $formats = array_map(fn ($path) => __DIR__.'/../../Resources/Fixtures/'.$path, [ + $formats = [ 'config/full.yml', - 'config/full.xml', 'config/full.php', - ]); + ]; + + // XML configuration is not supported in Symfony 8+ + if (class_exists('Symfony\Component\DependencyInjection\Loader\XmlFileLoader')) { + $formats[] = 'config/full.xml'; + } + + $formats = array_map(fn ($path) => __DIR__.'/../../Resources/Fixtures/'.$path, $formats); foreach ($formats as $format) { $this->assertProcessedConfigurationEquals($expectedConfiguration, [$format]); From a8c8d4c64789051d9202ca82a198a7169e99b44f Mon Sep 17 00:00:00 2001 From: Orest Divintari Date: Fri, 19 Dec 2025 21:26:52 +0200 Subject: [PATCH 5/8] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f5e5801..612a63a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,14 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee # Version 2 -# 2.2.0 - unreleased +# 2.3.0 - 2025-12-19 - Compatible with Symfony 8. + +# 2.2.0 - 2025-12-11 + - Replaced XML configuration with PHP configuration. +- Test with PHP 8.5. # 2.1.0 - 2024-11-24 From 68f858f07d82848aa75e67fa0367739fa9d44293 Mon Sep 17 00:00:00 2001 From: Orest Divintari Date: Fri, 19 Dec 2025 22:25:59 +0200 Subject: [PATCH 6/8] fix code style --- tests/Unit/DependencyInjection/ConfigurationTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index e85477bf..8fbc61c5 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -13,8 +13,6 @@ use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -use Symfony\Component\HttpKernel\Kernel; -use function class_exists; /** * @author David Buchmann @@ -117,7 +115,7 @@ protected function getConfiguration(): ConfigurationInterface public function testSupportsAllConfigFormats(): void { - if (!class_exists(Client::class)) { + if (!\class_exists(Client::class)) { $this->markTestSkipped('Guzzle 7 adapter is not installed'); } @@ -330,7 +328,7 @@ public function testSupportsAllConfigFormats(): void ]; // XML configuration is not supported in Symfony 8+ - if (class_exists('Symfony\Component\DependencyInjection\Loader\XmlFileLoader')) { + if (\class_exists('Symfony\Component\DependencyInjection\Loader\XmlFileLoader')) { $formats[] = 'config/full.xml'; } From f44e74921049b8f994c44564e4b1017d838285c0 Mon Sep 17 00:00:00 2001 From: Orest Divintari Date: Fri, 19 Dec 2025 22:32:31 +0200 Subject: [PATCH 7/8] fix cache-plugin error --- .github/workflows/continuous-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 3f966ffc..b901db9c 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -72,7 +72,7 @@ jobs: symfony-require: "7.4.*" php-version: "8.5" symfony-deprecations-helper: "weak" - - dependencies: "php-http/guzzle7-adapter symfony/http-client:^8" + - dependencies: "php-http/guzzle7-adapter php-http/cache-plugin:^2.0 symfony/http-client:^8" symfony-require: "8.0.*" php-version: "8.5" symfony-deprecations-helper: "weak" From fee90691c696f58ab1d3c22ca50a3e356f5d4ce6 Mon Sep 17 00:00:00 2001 From: Orest Divintari Date: Sat, 20 Dec 2025 04:31:20 +0200 Subject: [PATCH 8/8] Support cache-plugin 2.0 for Symfony 8 --- composer.json | 2 +- tests/Functional/ProfilingTest.php | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 7b32389f..0fce50ab 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,7 @@ "matthiasnoback/symfony-dependency-injection-test": "^4.3.1 || ^5.0 || ^6.2.0", "nyholm/nsa": "^1.1", "nyholm/psr7": "^1.2.1", - "php-http/cache-plugin": "^1.7", + "php-http/cache-plugin": "^1.7 || ^2.0", "php-http/mock-client": "^1.2", "php-http/promise": "^1.0", "php-http/throttle-plugin": "^1.1", diff --git a/tests/Functional/ProfilingTest.php b/tests/Functional/ProfilingTest.php index 4ade5ea9..1599d83f 100644 --- a/tests/Functional/ProfilingTest.php +++ b/tests/Functional/ProfilingTest.php @@ -7,8 +7,7 @@ use GuzzleHttp\Psr7\Request; use Http\Client\Common\Plugin; use Http\Client\Common\PluginClient; -use Http\Discovery\StreamFactoryDiscovery; -use Http\Discovery\UriFactoryDiscovery; +use Http\Discovery\Psr17FactoryDiscovery; use Http\HttplugBundle\Collector\Collector; use Http\HttplugBundle\Collector\Formatter; use Http\HttplugBundle\Collector\ProfileClient; @@ -40,7 +39,7 @@ public function setUp(): void public function testProfilingWithCachePlugin(): void { $client = $this->createClient([ - new Plugin\CachePlugin(new ArrayAdapter(), StreamFactoryDiscovery::find(), [ + new Plugin\CachePlugin(new ArrayAdapter(), Psr17FactoryDiscovery::findStreamFactory(), [ 'respect_response_cache_directives' => [], 'default_ttl' => 86400, ]), @@ -79,7 +78,7 @@ public function testProfilingWhenPluginThrowException(): void public function testProfiling(): void { $client = $this->createClient([ - new Plugin\AddHostPlugin(UriFactoryDiscovery::find()->createUri('https://example.com')), + new Plugin\AddHostPlugin(Psr17FactoryDiscovery::findUriFactory()->createUri('https://example.com')), new Plugin\RedirectPlugin(), new Plugin\RetryPlugin(), ]);