Merge pull request #2125 from acelaya-forks/feature/phpunit-11

Update to PHPUnit 11
This commit is contained in:
Alejandro Celaya 2024-05-12 13:22:26 +02:00
parent c6109fd396
commit de70ebe769
6 changed files with 38 additions and 22 deletions

View file

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
### Changed ### Changed
* Use new reusable workflow to publish docker image * Use new reusable workflow to publish docker image
* [#2015](https://github.com/shlinkio/shlink/issues/2015) Update to PHPUnit 11.
### Deprecated ### Deprecated
* *Nothing* * *Nothing*

View file

@ -28,7 +28,7 @@
"guzzlehttp/guzzle": "^7.5", "guzzlehttp/guzzle": "^7.5",
"jaybizzle/crawler-detect": "^1.2.116", "jaybizzle/crawler-detect": "^1.2.116",
"laminas/laminas-config": "^3.8", "laminas/laminas-config": "^3.8",
"laminas/laminas-config-aggregator": "^1.13", "laminas/laminas-config-aggregator": "^1.15",
"laminas/laminas-diactoros": "^3.3", "laminas/laminas-diactoros": "^3.3",
"laminas/laminas-inputfilter": "^2.27", "laminas/laminas-inputfilter": "^2.27",
"laminas/laminas-servicemanager": "^3.21", "laminas/laminas-servicemanager": "^3.21",
@ -67,9 +67,9 @@
"phpstan/phpstan-doctrine": "^1.3", "phpstan/phpstan-doctrine": "^1.3",
"phpstan/phpstan-phpunit": "^1.3", "phpstan/phpstan-phpunit": "^1.3",
"phpstan/phpstan-symfony": "^1.3", "phpstan/phpstan-symfony": "^1.3",
"phpunit/php-code-coverage": "^10.1", "phpunit/php-code-coverage": "^11.0",
"phpunit/phpcov": "^9.0", "phpunit/phpcov": "^10.0",
"phpunit/phpunit": "^10.4", "phpunit/phpunit": "^11.1",
"roave/security-advisories": "dev-master", "roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~2.3.0", "shlinkio/php-coding-standard": "~2.3.0",
"shlinkio/shlink-test-utils": "^4.1", "shlinkio/shlink-test-utils": "^4.1",

View file

@ -34,8 +34,8 @@ class MatomoSendVisitsCommandTest extends TestCase
} }
#[Test] #[Test]
#[TestWith([true])] #[TestWith([true], 'interactive')]
#[TestWith([false])] #[TestWith([false], 'not interactive')]
public function warningIsOnlyDisplayedInInteractiveMode(bool $interactive): void public function warningIsOnlyDisplayedInInteractiveMode(bool $interactive): void
{ {
$this->visitSender->method('sendVisitsInDateRange')->willReturn(new SendVisitsResult()); $this->visitSender->method('sendVisitsInDateRange')->willReturn(new SendVisitsResult());

View file

@ -25,6 +25,7 @@ class CliTestUtils
$command = $generator->testDouble( $command = $generator->testDouble(
Command::class, Command::class,
mockObject: true, mockObject: true,
markAsMockObject: true,
callOriginalConstructor: false, callOriginalConstructor: false,
callOriginalClone: false, callOriginalClone: false,
cloneArguments: false, cloneArguments: false,

View file

@ -10,6 +10,7 @@ use PHPUnit\Framework\Assert;
use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
@ -60,14 +61,19 @@ class NotFoundRedirectHandlerTest extends TestCase
public static function provideNonRedirectScenarios(): iterable public static function provideNonRedirectScenarios(): iterable
{ {
$exactly = static fn (int $expectedCount) => new InvokedCountMatcher($expectedCount);
$once = static fn () => $exactly(1);
yield 'no domain' => [function ( yield 'no domain' => [function (
MockObject&DomainServiceInterface $domainService, MockObject&DomainServiceInterface $domainService,
MockObject&NotFoundRedirectResolverInterface $resolver, MockObject&NotFoundRedirectResolverInterface $resolver,
) use (
$once,
): void { ): void {
$domainService->expects(self::once())->method('findByAuthority')->withAnyParameters()->willReturn( $domainService->expects($once())->method('findByAuthority')->withAnyParameters()->willReturn(
null, null,
); );
$resolver->expects(self::once())->method('resolveRedirectResponse')->with( $resolver->expects($once())->method('resolveRedirectResponse')->with(
self::isInstanceOf(NotFoundType::class), self::isInstanceOf(NotFoundType::class),
self::isInstanceOf(NotFoundRedirectOptions::class), self::isInstanceOf(NotFoundRedirectOptions::class),
self::isInstanceOf(UriInterface::class), self::isInstanceOf(UriInterface::class),
@ -76,12 +82,15 @@ class NotFoundRedirectHandlerTest extends TestCase
yield 'non-redirecting domain' => [function ( yield 'non-redirecting domain' => [function (
MockObject&DomainServiceInterface $domainService, MockObject&DomainServiceInterface $domainService,
MockObject&NotFoundRedirectResolverInterface $resolver, MockObject&NotFoundRedirectResolverInterface $resolver,
) use (
$once,
$exactly,
): void { ): void {
$domainService->expects(self::once())->method('findByAuthority')->withAnyParameters()->willReturn( $domainService->expects($once())->method('findByAuthority')->withAnyParameters()->willReturn(
Domain::withAuthority(''), Domain::withAuthority(''),
); );
$callCount = 0; $callCount = 0;
$resolver->expects(self::exactly(2))->method('resolveRedirectResponse')->willReturnCallback( $resolver->expects($exactly(2))->method('resolveRedirectResponse')->willReturnCallback(
function (mixed $arg1, mixed $arg2, mixed $arg3) use (&$callCount) { function (mixed $arg1, mixed $arg2, mixed $arg3) use (&$callCount) {
Assert::assertInstanceOf(NotFoundType::class, $arg1); Assert::assertInstanceOf(NotFoundType::class, $arg1);
Assert::assertInstanceOf($callCount === 0 ? Domain::class : NotFoundRedirectOptions::class, $arg2); Assert::assertInstanceOf($callCount === 0 ? Domain::class : NotFoundRedirectOptions::class, $arg2);

View file

@ -10,6 +10,7 @@ use Exception;
use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use RuntimeException; use RuntimeException;
@ -146,30 +147,34 @@ class NotifyVisitToRabbitMqTest extends TestCase
public static function providePayloads(): iterable public static function providePayloads(): iterable
{ {
$exactly = static fn (int $expectedCount) => new InvokedCountMatcher($expectedCount);
$once = static fn () => $exactly(1);
$never = static fn () => $exactly(0);
yield 'non-orphan visit' => [ yield 'non-orphan visit' => [
Visit::forValidShortUrl(ShortUrl::withLongUrl('https://longUrl'), Visitor::emptyInstance()), Visit::forValidShortUrl(ShortUrl::withLongUrl('https://longUrl'), Visitor::emptyInstance()),
function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void { function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator) use ($once, $never): void {
$update = Update::forTopicAndPayload('', []); $update = Update::forTopicAndPayload('', []);
$updatesGenerator->expects(self::never())->method('newOrphanVisitUpdate'); $updatesGenerator->expects($never())->method('newOrphanVisitUpdate');
$updatesGenerator->expects(self::once())->method('newVisitUpdate')->withAnyParameters()->willReturn( $updatesGenerator->expects($once())->method('newVisitUpdate')->withAnyParameters()->willReturn(
$update, $update,
); );
$updatesGenerator->expects(self::once())->method('newShortUrlVisitUpdate')->willReturn($update); $updatesGenerator->expects($once())->method('newShortUrlVisitUpdate')->willReturn($update);
}, },
function (MockObject & PublishingHelperInterface $helper): void { function (MockObject & PublishingHelperInterface $helper) use ($exactly): void {
$helper->expects(self::exactly(2))->method('publishUpdate')->with(self::isInstanceOf(Update::class)); $helper->expects($exactly(2))->method('publishUpdate')->with(self::isInstanceOf(Update::class));
}, },
]; ];
yield 'orphan visit' => [ yield 'orphan visit' => [
Visit::forBasePath(Visitor::emptyInstance()), Visit::forBasePath(Visitor::emptyInstance()),
function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator): void { function (MockObject & PublishingUpdatesGeneratorInterface $updatesGenerator) use ($once, $never): void {
$update = Update::forTopicAndPayload('', []); $update = Update::forTopicAndPayload('', []);
$updatesGenerator->expects(self::once())->method('newOrphanVisitUpdate')->willReturn($update); $updatesGenerator->expects($once())->method('newOrphanVisitUpdate')->willReturn($update);
$updatesGenerator->expects(self::never())->method('newVisitUpdate'); $updatesGenerator->expects($never())->method('newVisitUpdate');
$updatesGenerator->expects(self::never())->method('newShortUrlVisitUpdate'); $updatesGenerator->expects($never())->method('newShortUrlVisitUpdate');
}, },
function (MockObject & PublishingHelperInterface $helper): void { function (MockObject & PublishingHelperInterface $helper) use ($once): void {
$helper->expects(self::once())->method('publishUpdate')->with(self::isInstanceOf(Update::class)); $helper->expects($once())->method('publishUpdate')->with(self::isInstanceOf(Update::class));
}, },
]; ];
} }