Skip to content

Commit

Permalink
Merge branch '8.5' into 9.5
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Jan 27, 2021
2 parents 9459507 + eee79a1 commit c6f02fe
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
7 changes: 7 additions & 0 deletions src/Framework/Assert.php
Expand Up @@ -2534,6 +2534,13 @@ public static function isTrue(): IsTrue
return new IsTrue;
}

/**
* @psalm-template CallbackInput of mixed
*
* @psalm-param callable(mixed $callback): bool $callback
*
* @psalm-return Callback<CallbackInput>
*/
public static function callback(callable $callback): Callback
{
return new Callback($callback);
Expand Down
11 changes: 8 additions & 3 deletions src/Framework/Constraint/Callback.php
Expand Up @@ -9,18 +9,21 @@
*/
namespace PHPUnit\Framework\Constraint;

use function call_user_func;

/**
* @psalm-template CallbackInput of mixed
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
*/
final class Callback extends Constraint
{
/**
* @var callable
*
* @psalm-var callable(CallbackInput $input): bool
*/
private $callback;

/** @psalm-param callable(CallbackInput $input): bool $callback */
public function __construct(callable $callback)
{
$this->callback = $callback;
Expand All @@ -39,9 +42,11 @@ public function toString(): string
* constraint is met, false otherwise.
*
* @param mixed $other value or object to evaluate
*
* @psalm-param CallbackInput $other
*/
protected function matches($other): bool
{
return call_user_func($this->callback, $other);
return ($this->callback)($other);
}
}
54 changes: 54 additions & 0 deletions tests/static-analysis/TestUsingCallbacks.php
@@ -0,0 +1,54 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\StaticAnalysis;

use PHPUnit\Framework\TestCase;

/** @see https://www.youtube.com/watch?v=rXwMrBb2x1Q */
interface SayHello
{
public function hey(string $toPerson): string;
}

/** @small */
final class TestUsingCallbacks extends TestCase
{
public function testWillSayHelloAndCheckCallbackInput(): void
{
$mock = $this->createMock(SayHello::class);

$mock
->expects(self::once())
->method('hey')
->with(self::callback(static function (string $input): bool {
self::assertStringContainsString('Joe', $input);

return true;
}))
->willReturn('Hey Joe!');

self::assertSame('Hey Joe!', $mock->hey('Joe'));
}

public function testWillSayHelloAndCheckCallbackWithoutAnyInput(): void
{
$mock = $this->createMock(SayHello::class);

$mock
->expects(self::once())
->method('hey')
->with(self::callback(static function (): bool {
return true;
}))
->willReturn('Hey Joe!');

self::assertSame('Hey Joe!', $mock->hey('Joe'));
}
}

0 comments on commit c6f02fe

Please sign in to comment.