Merge pull request #232 from pestphp/feat/expect-extend

feat: makes expect extendable
This commit is contained in:
Nuno Maduro
2020-11-29 18:25:21 +01:00
committed by GitHub
6 changed files with 134 additions and 3 deletions

View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Pest\Concerns;
use BadMethodCallException;
use Closure;
/**
* @internal
*/
trait Extendable
{
/**
* @var array<string, Closure>
*/
private static $extends = [];
/**
* Register a custom extend.
*/
public static function extend(string $name, Closure $extend): void
{
static::$extends[$name] = $extend;
}
/**
* Checks if extend is registered.
*/
public static function hasExtend(string $name): bool
{
return array_key_exists($name, static::$extends);
}
/**
* Dynamically handle calls to the class.
*
* @param array<int, mixed> $parameters
*
* @return mixed
*
* @throws BadMethodCallException
*/
public function __call(string $method, array $parameters)
{
if (!static::hasExtend($method)) {
throw new BadMethodCallException(sprintf('Method %s::%s does not exist.', static::class, $method));
}
$extend = static::$extends[$method]->bindTo($this, static::class);
return $extend(...$parameters);
}
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Pest;
use Pest\Concerns\Extendable;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\Constraint\Constraint;
use SebastianBergmann\Exporter\Exporter;
@ -15,6 +16,8 @@ use SebastianBergmann\Exporter\Exporter;
*/
final class Expectation
{
use Extendable;
/**
* The expectation value.
*

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Pest\Support;
use Closure;
final class Extendable
{
/**
* The extendable class.
*
* @var string
*/
private $extendableClass;
/**
* Creates a new extendable instance.
*/
public function __construct(string $extendableClass)
{
$this->extendableClass = $extendableClass;
}
/**
* Register a custom extend.
*/
public function extend(string $name, Closure $extend): void
{
$this->extendableClass::extend($name, $extend);
}
}

View File

@ -9,6 +9,7 @@ use Pest\PendingObjects\BeforeEachCall;
use Pest\PendingObjects\TestCall;
use Pest\PendingObjects\UsesCall;
use Pest\Support\Backtrace;
use Pest\Support\Extendable;
use Pest\Support\HigherOrderTapProxy;
use Pest\TestSuite;
use PHPUnit\Framework\TestCase;
@ -111,9 +112,13 @@ function afterAll(Closure $closure = null): void
*
* @param mixed $value the Value
*
* @return Expectation
* @return Expectation|Extendable
*/
function expect($value)
function expect($value = null)
{
if (func_num_args() === 0) {
return new Extendable(Expectation::class);
}
return test()->expect($value);
}

View File

@ -2,6 +2,12 @@
PASS Tests\CustomTestCase\ExecutedTest
✓ that gets executed
PASS Tests\Expect\extend
✓ it macros true is true
✓ it macros false is not true
✓ it macros true is true with argument
✓ it macros false is not true with argument
PASS Tests\Expect\not
✓ not property calls
@ -404,5 +410,5 @@
✓ depends run test only once
✓ depends works with the correct test name
Tests: 7 skipped, 238 passed
Tests: 7 skipped, 242 passed

29
tests/Expect/extend.php Normal file
View File

@ -0,0 +1,29 @@
<?php
expect()->extend('toBeAMacroExpectation', function () {
$this->toBeTrue();
return $this;
});
expect()->extend('toBeAMacroExpectationWithArguments', function (bool $value) {
$this->toBe($value);
return $this;
});
it('macros true is true', function () {
expect(true)->toBeAMacroExpectation();
});
it('macros false is not true', function () {
expect(false)->not->toBeAMacroExpectation();
});
it('macros true is true with argument', function () {
expect(true)->toBeAMacroExpectationWithArguments(true);
});
it('macros false is not true with argument', function () {
expect(false)->not->toBeAMacroExpectationWithArguments(true);
});