Adds expect extend

This commit is contained in:
Nuno Maduro
2020-11-29 16:30:57 +01:00
parent b79ba5098b
commit 03dc11c2f6
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; namespace Pest;
use Pest\Concerns\Extendable;
use PHPUnit\Framework\Assert; use PHPUnit\Framework\Assert;
use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\Constraint\Constraint;
use SebastianBergmann\Exporter\Exporter; use SebastianBergmann\Exporter\Exporter;
@ -15,6 +16,8 @@ use SebastianBergmann\Exporter\Exporter;
*/ */
final class Expectation final class Expectation
{ {
use Extendable;
/** /**
* The expectation value. * 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\TestCall;
use Pest\PendingObjects\UsesCall; use Pest\PendingObjects\UsesCall;
use Pest\Support\Backtrace; use Pest\Support\Backtrace;
use Pest\Support\Extendable;
use Pest\Support\HigherOrderTapProxy; use Pest\Support\HigherOrderTapProxy;
use Pest\TestSuite; use Pest\TestSuite;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -111,9 +112,13 @@ function afterAll(Closure $closure = null): void
* *
* @param mixed $value the Value * @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); return test()->expect($value);
} }

View File

@ -2,6 +2,12 @@
PASS Tests\CustomTestCase\ExecutedTest PASS Tests\CustomTestCase\ExecutedTest
✓ that gets executed ✓ 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 PASS Tests\Expect\not
✓ not property calls ✓ not property calls
@ -404,5 +410,5 @@
✓ depends run test only once ✓ depends run test only once
✓ depends works with the correct test name ✓ 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);
});