mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
feat: move Expectations API out of external plugin
This commit is contained in:
@ -20,7 +20,6 @@
|
|||||||
"php": "^7.3 || ^8.0",
|
"php": "^7.3 || ^8.0",
|
||||||
"nunomaduro/collision": "^5.0",
|
"nunomaduro/collision": "^5.0",
|
||||||
"pestphp/pest-plugin": "^1.0",
|
"pestphp/pest-plugin": "^1.0",
|
||||||
"pestphp/pest-plugin-expectations": "^1.6",
|
|
||||||
"phpunit/phpunit": ">= 9.3.7 <= 9.5.5"
|
"phpunit/phpunit": ">= 9.3.7 <= 9.5.5"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|||||||
23
src/Concerns/Expectations.php
Normal file
23
src/Concerns/Expectations.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Concerns;
|
||||||
|
|
||||||
|
use Pest\Expectation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
trait Expectations
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new expectation.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function expect($value): Expectation
|
||||||
|
{
|
||||||
|
return new Expectation($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/Concerns/Extendable.php
Normal file
54
src/Concerns/Extendable.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Concerns;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Pest\HigherOrderExpectation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
public function __call(string $method, array $parameters)
|
||||||
|
{
|
||||||
|
if (!static::hasExtend($method)) {
|
||||||
|
return new HigherOrderExpectation($this, $method, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Closure $extend */
|
||||||
|
$extend = static::$extends[$method]->bindTo($this, static::class);
|
||||||
|
|
||||||
|
return $extend(...$parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/Each.php
Normal file
77
src/Each.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @mixin Expectation
|
||||||
|
*/
|
||||||
|
final class Each
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Expectation
|
||||||
|
*/
|
||||||
|
private $original;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $opposite = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an expectation on each item of the iterable "value".
|
||||||
|
*/
|
||||||
|
public function __construct(Expectation $original)
|
||||||
|
{
|
||||||
|
$this->original = $original;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new expectation.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function and($value): Expectation
|
||||||
|
{
|
||||||
|
return $this->original->and($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the opposite expectation for the value.
|
||||||
|
*/
|
||||||
|
public function not(): Each
|
||||||
|
{
|
||||||
|
$this->opposite = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically calls methods on the class with the given arguments on each item.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $arguments
|
||||||
|
*/
|
||||||
|
public function __call(string $name, array $arguments): Each
|
||||||
|
{
|
||||||
|
foreach ($this->original->value as $item) {
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
$this->opposite ? expect($item)->not()->$name(...$arguments) : expect($item)->$name(...$arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->opposite = false;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically calls methods on the class without any arguments on each item.
|
||||||
|
*/
|
||||||
|
public function __get(string $name): Each
|
||||||
|
{
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
return $this->$name();
|
||||||
|
}
|
||||||
|
}
|
||||||
714
src/Expectation.php
Normal file
714
src/Expectation.php
Normal file
@ -0,0 +1,714 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest;
|
||||||
|
|
||||||
|
use BadMethodCallException;
|
||||||
|
use Pest\Concerns\Extendable;
|
||||||
|
use PHPUnit\Framework\Assert;
|
||||||
|
use PHPUnit\Framework\Constraint\Constraint;
|
||||||
|
use SebastianBergmann\Exporter\Exporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @property Expectation $not Creates the opposite expectation.
|
||||||
|
* @property Each $each Creates an expectation on each element on the traversable value.
|
||||||
|
*/
|
||||||
|
final class Expectation
|
||||||
|
{
|
||||||
|
use Extendable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The expectation value.
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
public $value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The exporter instance, if any.
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
*
|
||||||
|
* @var Exporter|null
|
||||||
|
*/
|
||||||
|
private $exporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new expectation.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function __construct($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new expectation.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function and($value): Expectation
|
||||||
|
{
|
||||||
|
return new self($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump the expectation value and end the script.
|
||||||
|
*
|
||||||
|
* @param mixed $arguments
|
||||||
|
*
|
||||||
|
* @return never
|
||||||
|
*/
|
||||||
|
public function dd(...$arguments): void
|
||||||
|
{
|
||||||
|
if (function_exists('dd')) {
|
||||||
|
dd($this->value, ...$arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
var_dump($this->value);
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the expectation value to Ray along with all given arguments.
|
||||||
|
*
|
||||||
|
* @param mixed $arguments
|
||||||
|
*/
|
||||||
|
public function ray(...$arguments): self
|
||||||
|
{
|
||||||
|
if (function_exists('ray')) {
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
ray($this->value, ...$arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the opposite expectation for the value.
|
||||||
|
*/
|
||||||
|
public function not(): OppositeExpectation
|
||||||
|
{
|
||||||
|
return new OppositeExpectation($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an expectation on each item of the iterable "value".
|
||||||
|
*/
|
||||||
|
public function each(callable $callback = null): Each
|
||||||
|
{
|
||||||
|
if (!is_iterable($this->value)) {
|
||||||
|
throw new BadMethodCallException('Expectation value is not iterable.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_callable($callback)) {
|
||||||
|
foreach ($this->value as $item) {
|
||||||
|
$callback(expect($item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Each($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows you to specify a sequential set of expectations for each item in a iterable "value".
|
||||||
|
*/
|
||||||
|
public function sequence(callable ...$callbacks): Expectation
|
||||||
|
{
|
||||||
|
if (!is_iterable($this->value)) {
|
||||||
|
throw new BadMethodCallException('Expectation value is not iterable.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = is_array($this->value) ? $this->value : iterator_to_array($this->value);
|
||||||
|
$keys = array_keys($value);
|
||||||
|
$values = array_values($value);
|
||||||
|
|
||||||
|
$index = 0;
|
||||||
|
|
||||||
|
while (count($callbacks) < count($values)) {
|
||||||
|
$callbacks[] = $callbacks[$index];
|
||||||
|
$index = $index < count($values) - 1 ? $index + 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($values as $key => $item) {
|
||||||
|
call_user_func($callbacks[$key], expect($item), expect($keys[$key]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that two variables have the same type and
|
||||||
|
* value. Used on objects, it asserts that two
|
||||||
|
* variables reference the same object.
|
||||||
|
*
|
||||||
|
* @param mixed $expected
|
||||||
|
*/
|
||||||
|
public function toBe($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertSame($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is empty.
|
||||||
|
*/
|
||||||
|
public function toBeEmpty(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertEmpty($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is true.
|
||||||
|
*/
|
||||||
|
public function toBeTrue(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertTrue($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is false.
|
||||||
|
*/
|
||||||
|
public function toBeFalse(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertFalse($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is greater than $expected.
|
||||||
|
*
|
||||||
|
* @param int|float $expected
|
||||||
|
*/
|
||||||
|
public function toBeGreaterThan($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertGreaterThan($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is greater than or equal to $expected.
|
||||||
|
*
|
||||||
|
* @param int|float $expected
|
||||||
|
*/
|
||||||
|
public function toBeGreaterThanOrEqual($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertGreaterThanOrEqual($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is less than or equal to $expected.
|
||||||
|
*
|
||||||
|
* @param int|float $expected
|
||||||
|
*/
|
||||||
|
public function toBeLessThan($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertLessThan($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is less than $expected.
|
||||||
|
*
|
||||||
|
* @param int|float $expected
|
||||||
|
*/
|
||||||
|
public function toBeLessThanOrEqual($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertLessThanOrEqual($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that $needle is an element of the value.
|
||||||
|
*
|
||||||
|
* @param mixed $needle
|
||||||
|
*/
|
||||||
|
public function toContain($needle): Expectation
|
||||||
|
{
|
||||||
|
if (is_string($this->value)) {
|
||||||
|
Assert::assertStringContainsString($needle, $this->value);
|
||||||
|
} else {
|
||||||
|
Assert::assertContains($needle, $this->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value starts with $expected.
|
||||||
|
*/
|
||||||
|
public function toStartWith(string $expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertStringStartsWith($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value ends with $expected.
|
||||||
|
*/
|
||||||
|
public function toEndWith(string $expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertStringEndsWith($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that $count matches the number of elements of the value.
|
||||||
|
*/
|
||||||
|
public function toHaveCount(int $count): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertCount($count, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value contains the property $name.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function toHaveProperty(string $name, $value = null): Expectation
|
||||||
|
{
|
||||||
|
$this->toBeObject();
|
||||||
|
|
||||||
|
Assert::assertTrue(property_exists($this->value, $name));
|
||||||
|
|
||||||
|
if (func_num_args() > 1) {
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
Assert::assertEquals($value, $this->value->{$name});
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that two variables have the same value.
|
||||||
|
*
|
||||||
|
* @param mixed $expected
|
||||||
|
*/
|
||||||
|
public function toEqual($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertEquals($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that two variables have the same value.
|
||||||
|
* The contents of $expected and the $this->value are
|
||||||
|
* canonicalized before they are compared. For instance, when the two
|
||||||
|
* variables $expected and $this->value are arrays, then these arrays
|
||||||
|
* are sorted before they are compared. When $expected and $this->value
|
||||||
|
* are objects, each object is converted to an array containing all
|
||||||
|
* private, protected and public attributes.
|
||||||
|
*
|
||||||
|
* @param mixed $expected
|
||||||
|
*/
|
||||||
|
public function toEqualCanonicalizing($expected): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertEqualsCanonicalizing($expected, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the absolute difference between the value and $expected
|
||||||
|
* is lower than $delta.
|
||||||
|
*
|
||||||
|
* @param mixed $expected
|
||||||
|
*/
|
||||||
|
public function toEqualWithDelta($expected, float $delta): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertEqualsWithDelta($expected, $this->value, $delta);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is infinite.
|
||||||
|
*/
|
||||||
|
public function toBeInfinite(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertInfinite($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is an instance of $class.
|
||||||
|
*
|
||||||
|
* @param string $class
|
||||||
|
*/
|
||||||
|
public function toBeInstanceOf($class): Expectation
|
||||||
|
{
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
Assert::assertInstanceOf($class, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is an array.
|
||||||
|
*/
|
||||||
|
public function toBeArray(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsArray($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type bool.
|
||||||
|
*/
|
||||||
|
public function toBeBool(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsBool($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type callable.
|
||||||
|
*/
|
||||||
|
public function toBeCallable(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsCallable($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type float.
|
||||||
|
*/
|
||||||
|
public function toBeFloat(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsFloat($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type int.
|
||||||
|
*/
|
||||||
|
public function toBeInt(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsInt($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type iterable.
|
||||||
|
*/
|
||||||
|
public function toBeIterable(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsIterable($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type numeric.
|
||||||
|
*/
|
||||||
|
public function toBeNumeric(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsNumeric($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type object.
|
||||||
|
*/
|
||||||
|
public function toBeObject(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsObject($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type resource.
|
||||||
|
*/
|
||||||
|
public function toBeResource(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsResource($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type scalar.
|
||||||
|
*/
|
||||||
|
public function toBeScalar(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsScalar($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is of type string.
|
||||||
|
*/
|
||||||
|
public function toBeString(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsString($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a JSON string.
|
||||||
|
*/
|
||||||
|
public function toBeJson(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertIsString($this->value);
|
||||||
|
Assert::assertJson($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is NAN.
|
||||||
|
*/
|
||||||
|
public function toBeNan(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertNan($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is null.
|
||||||
|
*/
|
||||||
|
public function toBeNull(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertNull($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value array has the provided $key.
|
||||||
|
*
|
||||||
|
* @param string|int $key
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function toHaveKey($key, $value = null): Expectation
|
||||||
|
{
|
||||||
|
if (is_object($this->value) && method_exists($this->value, 'toArray')) {
|
||||||
|
$array = $this->value->toArray();
|
||||||
|
} else {
|
||||||
|
$array = (array) $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert::assertArrayHasKey($key, $array);
|
||||||
|
|
||||||
|
if (func_num_args() > 1) {
|
||||||
|
Assert::assertEquals($value, $array[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value array has the provided $keys.
|
||||||
|
*
|
||||||
|
* @param array<int, int|string> $keys
|
||||||
|
*/
|
||||||
|
public function toHaveKeys(array $keys): Expectation
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$this->toHaveKey($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a directory.
|
||||||
|
*/
|
||||||
|
public function toBeDirectory(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertDirectoryExists($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a directory and is readable.
|
||||||
|
*/
|
||||||
|
public function toBeReadableDirectory(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertDirectoryIsReadable($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a directory and is writable.
|
||||||
|
*/
|
||||||
|
public function toBeWritableDirectory(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertDirectoryIsWritable($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a file.
|
||||||
|
*/
|
||||||
|
public function toBeFile(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertFileExists($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a file and is readable.
|
||||||
|
*/
|
||||||
|
public function toBeReadableFile(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertFileIsReadable($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value is a file and is writable.
|
||||||
|
*/
|
||||||
|
public function toBeWritableFile(): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertFileIsWritable($this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value array matches the given array subset.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $array
|
||||||
|
*/
|
||||||
|
public function toMatchArray($array): Expectation
|
||||||
|
{
|
||||||
|
if (is_object($this->value) && method_exists($this->value, 'toArray')) {
|
||||||
|
$valueAsArray = $this->value->toArray();
|
||||||
|
} else {
|
||||||
|
$valueAsArray = (array) $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
|
Assert::assertArrayHasKey($key, $valueAsArray);
|
||||||
|
|
||||||
|
Assert::assertEquals(
|
||||||
|
$value,
|
||||||
|
$valueAsArray[$key],
|
||||||
|
sprintf(
|
||||||
|
'Failed asserting that an array has a key %s with the value %s.',
|
||||||
|
$this->export($key),
|
||||||
|
$this->export($valueAsArray[$key]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value object matches a subset
|
||||||
|
* of the properties of an given object.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed>|object $object
|
||||||
|
*/
|
||||||
|
public function toMatchObject($object): Expectation
|
||||||
|
{
|
||||||
|
foreach ((array) $object as $property => $value) {
|
||||||
|
Assert::assertTrue(property_exists($this->value, $property));
|
||||||
|
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
$propertyValue = $this->value->{$property};
|
||||||
|
Assert::assertEquals(
|
||||||
|
$value,
|
||||||
|
$propertyValue,
|
||||||
|
sprintf(
|
||||||
|
'Failed asserting that an object has a property %s with the value %s.',
|
||||||
|
$this->export($property),
|
||||||
|
$this->export($propertyValue),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value matches a regular expression.
|
||||||
|
*/
|
||||||
|
public function toMatch(string $expression): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertMatchesRegularExpression($expression, $this->value);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value matches a constraint.
|
||||||
|
*/
|
||||||
|
public function toMatchConstraint(Constraint $constraint): Expectation
|
||||||
|
{
|
||||||
|
Assert::assertThat($this->value, $constraint);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exports the given value.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
private function export($value): string
|
||||||
|
{
|
||||||
|
if ($this->exporter === null) {
|
||||||
|
$this->exporter = new Exporter();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->exporter->export($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically calls methods on the class without any arguments
|
||||||
|
* or creates a new higher order expectation.
|
||||||
|
*
|
||||||
|
* @return Expectation|HigherOrderExpectation
|
||||||
|
*/
|
||||||
|
public function __get(string $name)
|
||||||
|
{
|
||||||
|
if (!method_exists($this, $name) && !static::hasExtend($name)) {
|
||||||
|
return new HigherOrderExpectation($this, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
return $this->{$name}();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -80,6 +80,7 @@ final class TestCaseFactory
|
|||||||
*/
|
*/
|
||||||
public $traits = [
|
public $traits = [
|
||||||
Concerns\TestCase::class,
|
Concerns\TestCase::class,
|
||||||
|
Concerns\Expectations::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,15 +3,33 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Pest\Datasets;
|
use Pest\Datasets;
|
||||||
|
use Pest\Expectation;
|
||||||
use Pest\PendingObjects\AfterEachCall;
|
use Pest\PendingObjects\AfterEachCall;
|
||||||
use Pest\PendingObjects\BeforeEachCall;
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new expectation.
|
||||||
|
*
|
||||||
|
* @param mixed $value the Value
|
||||||
|
*
|
||||||
|
* @return Expectation|Extendable
|
||||||
|
*/
|
||||||
|
function expect($value = null)
|
||||||
|
{
|
||||||
|
if (func_num_args() === 0) {
|
||||||
|
return new Extendable(Expectation::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Expectation($value);
|
||||||
|
}
|
||||||
|
|
||||||
if (!function_exists('beforeAll')) {
|
if (!function_exists('beforeAll')) {
|
||||||
/**
|
/**
|
||||||
* Runs the given closure before all tests in the current file.
|
* Runs the given closure before all tests in the current file.
|
||||||
|
|||||||
147
src/HigherOrderExpectation.php
Normal file
147
src/HigherOrderExpectation.php
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest;
|
||||||
|
|
||||||
|
use Pest\Concerns\Expectations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @mixin Expectation
|
||||||
|
*/
|
||||||
|
final class HigherOrderExpectation
|
||||||
|
{
|
||||||
|
use Expectations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Expectation
|
||||||
|
*/
|
||||||
|
private $original;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Expectation|Each
|
||||||
|
*/
|
||||||
|
private $expectation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $opposite = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new higher order expectation.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed>|null $parameters
|
||||||
|
* @phpstan-ignore-next-line
|
||||||
|
*/
|
||||||
|
public function __construct(Expectation $original, string $name, ?array $parameters = null)
|
||||||
|
{
|
||||||
|
$this->original = $original;
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
$this->expectation = $this->expect(
|
||||||
|
is_null($parameters) ? $this->getPropertyValue() : $this->getMethodValue($parameters)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the property value from the original expectation.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function getPropertyValue()
|
||||||
|
{
|
||||||
|
if (is_array($this->original->value)) {
|
||||||
|
return $this->original->value[$this->name];
|
||||||
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
return $this->original->value->{$this->name};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value of the method from the original expectation.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $arguments
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function getMethodValue(array $arguments)
|
||||||
|
{
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
return $this->original->value->{$this->name}(...$arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the opposite expectation for the value.
|
||||||
|
*/
|
||||||
|
public function not(): HigherOrderExpectation
|
||||||
|
{
|
||||||
|
$this->opposite = !$this->opposite;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically calls methods on the class with the given arguments.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $arguments
|
||||||
|
*/
|
||||||
|
public function __call(string $name, array $arguments): self
|
||||||
|
{
|
||||||
|
if (!$this->originalHasMethod($name)) {
|
||||||
|
return new self($this->original, $name, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->performAssertion($name, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accesses properties in the value or in the expectation.
|
||||||
|
*/
|
||||||
|
public function __get(string $name): self
|
||||||
|
{
|
||||||
|
if ($name === 'not') {
|
||||||
|
return $this->not();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->originalHasMethod($name)) {
|
||||||
|
return new self($this->original, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->performAssertion($name, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the original expectation has the given method name.
|
||||||
|
*/
|
||||||
|
private function originalHasMethod(string $name): bool
|
||||||
|
{
|
||||||
|
return method_exists($this->original, $name) || $this->original::hasExtend($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the given assertion with the current expectation.
|
||||||
|
*
|
||||||
|
* @param array<int|string, mixed> $arguments
|
||||||
|
*/
|
||||||
|
private function performAssertion(string $name, array $arguments): self
|
||||||
|
{
|
||||||
|
$expectation = $this->opposite
|
||||||
|
? $this->expectation->not()
|
||||||
|
: $this->expectation;
|
||||||
|
|
||||||
|
$this->expectation = $expectation->{$name}(...$arguments); // @phpstan-ignore-line
|
||||||
|
|
||||||
|
$this->opposite = false;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
99
src/OppositeExpectation.php
Normal file
99
src/OppositeExpectation.php
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
use SebastianBergmann\Exporter\Exporter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @mixin Expectation
|
||||||
|
*/
|
||||||
|
final class OppositeExpectation
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Expectation
|
||||||
|
*/
|
||||||
|
private $original;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new opposite expectation.
|
||||||
|
*/
|
||||||
|
public function __construct(Expectation $original)
|
||||||
|
{
|
||||||
|
$this->original = $original;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the value array not has the provided $keys.
|
||||||
|
*
|
||||||
|
* @param array<int, int|string> $keys
|
||||||
|
*/
|
||||||
|
public function toHaveKeys(array $keys): Expectation
|
||||||
|
{
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
try {
|
||||||
|
$this->original->toHaveKey($key);
|
||||||
|
} catch (ExpectationFailedException $e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->throwExpectationFailedException('toHaveKey', [$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->original;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle dynamic method calls into the original expectation.
|
||||||
|
*
|
||||||
|
* @param array<int, mixed> $arguments
|
||||||
|
*/
|
||||||
|
public function __call(string $name, array $arguments): Expectation
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
$this->original->{$name}(...$arguments);
|
||||||
|
} catch (ExpectationFailedException $e) {
|
||||||
|
return $this->original;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
$this->throwExpectationFailedException($name, $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle dynamic properties gets into the original expectation.
|
||||||
|
*/
|
||||||
|
public function __get(string $name): Expectation
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
$this->original->{$name};
|
||||||
|
} catch (ExpectationFailedException $e) {
|
||||||
|
return $this->original;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @phpstan-ignore-next-line
|
||||||
|
$this->throwExpectationFailedException($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new expectation failed exception with a nice readable message.
|
||||||
|
*
|
||||||
|
* @param array<int, mixed> $arguments
|
||||||
|
*/
|
||||||
|
private function throwExpectationFailedException(string $name, array $arguments = []): void
|
||||||
|
{
|
||||||
|
$exporter = new Exporter();
|
||||||
|
|
||||||
|
$toString = function ($argument) use ($exporter): string {
|
||||||
|
return $exporter->shortenedExport($argument);
|
||||||
|
};
|
||||||
|
|
||||||
|
throw new ExpectationFailedException(sprintf('Expecting %s not %s %s.', $toString($this->original->value), strtolower((string) preg_replace('/(?<!\ )[A-Z]/', ' $0', $name)), implode(' ', array_map(function ($argument) use ($toString): string { return $toString($argument); }, $arguments))));
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/Support/Extendable.php
Normal file
33
src/Support/Extendable.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -102,6 +102,278 @@
|
|||||||
✓ it catch exceptions
|
✓ it catch exceptions
|
||||||
✓ it catch exceptions and messages
|
✓ it catch exceptions and messages
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\HigherOrder\methods
|
||||||
|
✓ it can access methods
|
||||||
|
✓ it can access multiple methods
|
||||||
|
✓ it works with not
|
||||||
|
✓ it can accept arguments
|
||||||
|
✓ it works with each
|
||||||
|
✓ it works inside of each
|
||||||
|
✓ it works with sequence
|
||||||
|
✓ it can compose complex expectations
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\HigherOrder\methodsAndProperties
|
||||||
|
✓ it can access methods and properties
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\HigherOrder\properties
|
||||||
|
✓ it allows properties to be accessed from the value
|
||||||
|
✓ it can access multiple properties from the value
|
||||||
|
✓ it works with not
|
||||||
|
✓ it works with each
|
||||||
|
✓ it works inside of each
|
||||||
|
✓ it works with sequence
|
||||||
|
✓ it can compose complex expectations
|
||||||
|
✓ it works with objects
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\each
|
||||||
|
✓ an exception is thrown if the the type is not iterable
|
||||||
|
✓ it expects on each item
|
||||||
|
✓ it chains expectations on each item
|
||||||
|
✓ opposite expectations on each item
|
||||||
|
✓ chained opposite and non-opposite expectations
|
||||||
|
✓ it can add expectations via "and"
|
||||||
|
✓ it accepts callables
|
||||||
|
|
||||||
|
PASS Tests\Features\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\Features\Expect\not
|
||||||
|
✓ not property calls
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\ray
|
||||||
|
✓ ray calls do not fail when ray is not installed
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\sequence
|
||||||
|
✓ an exception is thrown if the the type is not iterable
|
||||||
|
✓ allows for sequences of checks to be run on iterable data
|
||||||
|
✓ loops back to the start if it runs out of sequence items
|
||||||
|
✓ it works if the number of items in the iterable is smaller than the number of expectations
|
||||||
|
✓ it works with associative arrays
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBe
|
||||||
|
✓ strict comparisons
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeArray
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeBool
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeCallable
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeDirectory
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeEmpty
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeFalse
|
||||||
|
✓ strict comparisons
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeFile
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeFloat
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeGreatherThan
|
||||||
|
✓ passes
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeGreatherThanOrEqual
|
||||||
|
✓ passes
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeInfinite
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeInstanceOf
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeInt
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeIterable
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeJson
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeLessThan
|
||||||
|
✓ passes
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeLessThanOrEqual
|
||||||
|
✓ passes
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeNAN
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeNull
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeNumeric
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeObject
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeReadableDirectory
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeReadableFile
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeResource
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeScalar
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeString
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeTrue
|
||||||
|
✓ strict comparisons
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeWritableDirectory
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toBeWritableFile
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toContain
|
||||||
|
✓ passes strings
|
||||||
|
✓ passes arrays
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toEndWith
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toEqual
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toEqualCanonicalizing
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toEqualWithDelta
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHaveCount
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHaveKey
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHaveKeys
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toHaveProperty
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toMatch
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toMatchArray
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toMatchConstraint
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toMatchObject
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
|
PASS Tests\Features\Expect\toStartWith
|
||||||
|
✓ pass
|
||||||
|
✓ failures
|
||||||
|
✓ not failures
|
||||||
|
|
||||||
PASS Tests\Features\Helpers
|
PASS Tests\Features\Helpers
|
||||||
✓ it can set/get properties on $this
|
✓ it can set/get properties on $this
|
||||||
✓ it throws error if property do not exist
|
✓ it throws error if property do not exist
|
||||||
@ -282,5 +554,5 @@
|
|||||||
✓ it is a test
|
✓ it is a test
|
||||||
✓ it uses correct parent class
|
✓ it uses correct parent class
|
||||||
|
|
||||||
Tests: 4 incompleted, 7 skipped, 172 passed
|
Tests: 4 incompleted, 7 skipped, 340 passed
|
||||||
|
|
||||||
100
tests/Features/Expect/HigherOrder/methods.php
Normal file
100
tests/Features/Expect/HigherOrder/methods.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
it('can access methods', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->name()->toBeString()->toEqual('Has Methods');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can access multiple methods', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->name()->toBeString()->toEqual('Has Methods')
|
||||||
|
->quantity()->toBeInt()->toEqual(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with not', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->name()->not->toEqual('world')->toEqual('Has Methods')
|
||||||
|
->quantity()->toEqual(20)->not()->toEqual('bar')->not->toBeNull;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can accept arguments', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->multiply(5, 4)->toBeInt->toEqual(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with each', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->attributes()->toBeArray->each->not()->toBeNull
|
||||||
|
->attributes()->each(function ($attribute) {
|
||||||
|
$attribute->not->toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works inside of each', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->books()->each(function ($book) {
|
||||||
|
$book->title->not->toBeNull->cost->toBeGreaterThan(19);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with sequence', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->books()->sequence(
|
||||||
|
function ($book) { $book->title->toEqual('Foo')->cost->toEqual(20); },
|
||||||
|
function ($book) { $book->title->toEqual('Bar')->cost->toEqual(30); },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can compose complex expectations', function () {
|
||||||
|
expect(new HasMethods())
|
||||||
|
->toBeObject()
|
||||||
|
->name()->toEqual('Has Methods')->not()->toEqual('bar')
|
||||||
|
->quantity()->not->toEqual('world')->toEqual(20)->toBeInt
|
||||||
|
->multiply(3, 4)->not->toBeString->toEqual(12)
|
||||||
|
->attributes()->toBeArray()
|
||||||
|
->books()->toBeArray->each->not->toBeEmpty
|
||||||
|
->books()->sequence(
|
||||||
|
function ($book) { $book->title->toEqual('Foo')->cost->toEqual(20); },
|
||||||
|
function ($book) { $book->title->toEqual('Bar')->cost->toEqual(30); },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
class HasMethods
|
||||||
|
{
|
||||||
|
public function name()
|
||||||
|
{
|
||||||
|
return 'Has Methods';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function quantity()
|
||||||
|
{
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function multiply($x, $y)
|
||||||
|
{
|
||||||
|
return $x * $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attributes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'name' => $this->name(),
|
||||||
|
'quantity' => $this->quantity(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function books()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'title' => 'Foo',
|
||||||
|
'cost' => 20,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'title' => 'Bar',
|
||||||
|
'cost' => 30,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
50
tests/Features/Expect/HigherOrder/methodsAndProperties.php
Normal file
50
tests/Features/Expect/HigherOrder/methodsAndProperties.php
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
it('can access methods and properties', function () {
|
||||||
|
expect(new HasMethodsAndProperties())
|
||||||
|
->name->toEqual('Has Methods and Properties')->not()->toEqual('bar')
|
||||||
|
->multiply(3, 4)->not->toBeString->toEqual(12)
|
||||||
|
->posts->each(function ($post) {
|
||||||
|
$post->is_published->toBeTrue;
|
||||||
|
})->books()->toBeArray()
|
||||||
|
->posts->toBeArray->each->not->toBeEmpty
|
||||||
|
->books()->sequence(
|
||||||
|
function ($book) { $book->title->toEqual('Foo')->cost->toEqual(20); },
|
||||||
|
function ($book) { $book->title->toEqual('Bar')->cost->toEqual(30); },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
class HasMethodsAndProperties
|
||||||
|
{
|
||||||
|
public $name = 'Has Methods and Properties';
|
||||||
|
|
||||||
|
public $posts = [
|
||||||
|
[
|
||||||
|
'is_published' => true,
|
||||||
|
'title' => 'Foo',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'is_published' => true,
|
||||||
|
'title' => 'Bar',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function books()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'title' => 'Foo',
|
||||||
|
'cost' => 20,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'title' => 'Bar',
|
||||||
|
'cost' => 30,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function multiply($x, $y)
|
||||||
|
{
|
||||||
|
return $x * $y;
|
||||||
|
}
|
||||||
|
}
|
||||||
75
tests/Features/Expect/HigherOrder/properties.php
Normal file
75
tests/Features/Expect/HigherOrder/properties.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
it('allows properties to be accessed from the value', function () {
|
||||||
|
expect(['foo' => 1])->foo->toBeInt()->toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can access multiple properties from the value', function () {
|
||||||
|
expect(['foo' => 'bar', 'hello' => 'world'])
|
||||||
|
->foo->toBeString()->toEqual('bar')
|
||||||
|
->hello->toBeString()->toEqual('world');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with not', function () {
|
||||||
|
expect(['foo' => 'bar', 'hello' => 'world'])
|
||||||
|
->foo->not->not->toEqual('bar')
|
||||||
|
->foo->not->toEqual('world')->toEqual('bar')
|
||||||
|
->hello->toEqual('world')->not()->toEqual('bar')->not->toBeNull;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with each', function () {
|
||||||
|
expect(['numbers' => [1, 2, 3, 4], 'words' => ['hey', 'there']])
|
||||||
|
->numbers->toEqual([1, 2, 3, 4])->each->toBeInt->toBeLessThan(5)
|
||||||
|
->words->each(function ($word) {
|
||||||
|
$word->toBeString()->not->toBeInt();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works inside of each', function () {
|
||||||
|
expect(['books' => [['title' => 'Foo', 'cost' => 20], ['title' => 'Bar', 'cost' => 30]]])
|
||||||
|
->books->each(function ($book) {
|
||||||
|
$book->title->not->toBeNull->cost->toBeGreaterThan(19);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with sequence', function () {
|
||||||
|
expect(['books' => [['title' => 'Foo', 'cost' => 20], ['title' => 'Bar', 'cost' => 30]]])
|
||||||
|
->books->sequence(
|
||||||
|
function ($book) { $book->title->toEqual('Foo')->cost->toEqual(20); },
|
||||||
|
function ($book) { $book->title->toEqual('Bar')->cost->toEqual(30); },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can compose complex expectations', function () {
|
||||||
|
expect(['foo' => 'bar', 'numbers' => [1, 2, 3, 4]])
|
||||||
|
->toContain('bar')->toBeArray()
|
||||||
|
->numbers->toEqual([1, 2, 3, 4])->not()->toEqual('bar')->each->toBeInt
|
||||||
|
->foo->not->toEqual('world')->toEqual('bar')
|
||||||
|
->numbers->toBeArray();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with objects', function () {
|
||||||
|
expect(new HasProperties())
|
||||||
|
->name->toEqual('foo')->not->toEqual('world')
|
||||||
|
->posts->toHaveCount(2)->each(function ($post) { $post->is_published->toBeTrue(); })
|
||||||
|
->posts->sequence(
|
||||||
|
function ($post) { $post->title->toEqual('Foo'); },
|
||||||
|
function ($post) { $post->title->toEqual('Bar'); },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
class HasProperties
|
||||||
|
{
|
||||||
|
public $name = 'foo';
|
||||||
|
|
||||||
|
public $posts = [
|
||||||
|
[
|
||||||
|
'is_published' => true,
|
||||||
|
'title' => 'Foo',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'is_published' => true,
|
||||||
|
'title' => 'Bar',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
89
tests/Features/Expect/each.php
Normal file
89
tests/Features/Expect/each.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Pest\Expectation;
|
||||||
|
|
||||||
|
test('an exception is thrown if the the type is not iterable', function () {
|
||||||
|
expect('Foobar')->each()->toEqual('Foobar');
|
||||||
|
})->throws(BadMethodCallException::class, 'Expectation value is not iterable.');
|
||||||
|
|
||||||
|
it('expects on each item', function () {
|
||||||
|
expect([1, 1, 1])
|
||||||
|
->each()
|
||||||
|
->toEqual(1);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(3); // + 1 assertion
|
||||||
|
|
||||||
|
expect([1, 1, 1])
|
||||||
|
->each
|
||||||
|
->toEqual(1);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('chains expectations on each item', function () {
|
||||||
|
expect([1, 1, 1])
|
||||||
|
->each()
|
||||||
|
->toBeInt()
|
||||||
|
->toEqual(1);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(6); // + 1 assertion
|
||||||
|
|
||||||
|
expect([2, 2, 2])
|
||||||
|
->each
|
||||||
|
->toBeInt
|
||||||
|
->toEqual(2);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(13);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('opposite expectations on each item', function () {
|
||||||
|
expect([1, 2, 3])
|
||||||
|
->each()
|
||||||
|
->not()
|
||||||
|
->toEqual(4);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(3);
|
||||||
|
|
||||||
|
expect([1, 2, 3])
|
||||||
|
->each()
|
||||||
|
->not->toBeString;
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('chained opposite and non-opposite expectations', function () {
|
||||||
|
expect([1, 2, 3])
|
||||||
|
->each()
|
||||||
|
->not()
|
||||||
|
->toEqual(4)
|
||||||
|
->toBeInt();
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can add expectations via "and"', function () {
|
||||||
|
expect([1, 2, 3])
|
||||||
|
->each()
|
||||||
|
->toBeInt // + 3
|
||||||
|
->and([4, 5, 6])
|
||||||
|
->each
|
||||||
|
->toBeLessThan(7) // + 3
|
||||||
|
->not
|
||||||
|
->toBeLessThan(3)
|
||||||
|
->toBeGreaterThan(3) // + 3
|
||||||
|
->and('Hello World')
|
||||||
|
->toBeString // + 1
|
||||||
|
->toEqual('Hello World'); // + 1
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(14);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts callables', function () {
|
||||||
|
expect([1, 2, 3])->each(function ($number) {
|
||||||
|
expect($number)->toBeInstanceOf(Expectation::class);
|
||||||
|
expect($number->value)->toBeInt();
|
||||||
|
$number->toBeInt->not->toBeString;
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(12);
|
||||||
|
});
|
||||||
29
tests/Features/Expect/extend.php
Normal file
29
tests/Features/Expect/extend.php
Normal 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);
|
||||||
|
});
|
||||||
10
tests/Features/Expect/not.php
Normal file
10
tests/Features/Expect/not.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
test('not property calls', function () {
|
||||||
|
expect(true)
|
||||||
|
->toBeTrue()
|
||||||
|
->not()->toBeFalse()
|
||||||
|
->not->toBeFalse
|
||||||
|
->and(false)
|
||||||
|
->toBeFalse();
|
||||||
|
});
|
||||||
5
tests/Features/Expect/ray.php
Normal file
5
tests/Features/Expect/ray.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
test('ray calls do not fail when ray is not installed', function () {
|
||||||
|
expect(true)->ray()->toBe(true);
|
||||||
|
});
|
||||||
46
tests/Features/Expect/sequence.php
Normal file
46
tests/Features/Expect/sequence.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
test('an exception is thrown if the the type is not iterable', function () {
|
||||||
|
expect('Foobar')->each->sequence();
|
||||||
|
})->throws(BadMethodCallException::class, 'Expectation value is not iterable.');
|
||||||
|
|
||||||
|
test('allows for sequences of checks to be run on iterable data', function () {
|
||||||
|
expect([1, 2, 3])
|
||||||
|
->sequence(
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(3); },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('loops back to the start if it runs out of sequence items', function () {
|
||||||
|
expect([1, 2, 3, 1, 2, 3, 1, 2])
|
||||||
|
->sequence(
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(3); },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(16);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it works if the number of items in the iterable is smaller than the number of expectations', function () {
|
||||||
|
expect([1, 2])
|
||||||
|
->sequence(
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(1); },
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(2); },
|
||||||
|
function ($expectation) { $expectation->toBeInt()->toEqual(3); },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(static::getCount())->toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it works with associative arrays', function () {
|
||||||
|
expect(['foo' => 'bar', 'baz' => 'boom'])
|
||||||
|
->sequence(
|
||||||
|
function ($expectation, $key) { $expectation->toEqual('bar'); $key->toEqual('foo'); },
|
||||||
|
function ($expectation, $key) { $expectation->toEqual('boom'); $key->toEqual('baz'); },
|
||||||
|
);
|
||||||
|
});
|
||||||
20
tests/Features/Expect/toBe.php
Normal file
20
tests/Features/Expect/toBe.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
expect(true)->toBeTrue()->and(false)->toBeFalse();
|
||||||
|
|
||||||
|
test('strict comparisons', function () {
|
||||||
|
$nuno = new stdClass();
|
||||||
|
$dries = new stdClass();
|
||||||
|
|
||||||
|
expect($nuno)->toBe($nuno)->not->toBe($dries);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(1)->toBe(2);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(1)->not->toBe(1);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeArray.php
Normal file
16
tests/Features/Expect/toBeArray.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect([1, 2, 3])->toBeArray();
|
||||||
|
expect('1, 2, 3')->not->toBeArray();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeArray();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(['a', 'b', 'c'])->not->toBeArray();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeBool.php
Normal file
16
tests/Features/Expect/toBeBool.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(true)->toBeBool();
|
||||||
|
expect(0)->not->toBeBool();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeBool();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(false)->not->toBeBool();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
18
tests/Features/Expect/toBeCallable.php
Normal file
18
tests/Features/Expect/toBeCallable.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(function () {})->toBeCallable();
|
||||||
|
expect(null)->not->toBeCallable();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
$hello = 5;
|
||||||
|
|
||||||
|
expect($hello)->toBeCallable();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(function () { return 42; })->not->toBeCallable();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
17
tests/Features/Expect/toBeDirectory.php
Normal file
17
tests/Features/Expect/toBeDirectory.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
$temp = sys_get_temp_dir();
|
||||||
|
|
||||||
|
expect($temp)->toBeDirectory();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('/random/path/whatever')->toBeDirectory();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('.')->not->toBeDirectory();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
18
tests/Features/Expect/toBeEmpty.php
Normal file
18
tests/Features/Expect/toBeEmpty.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect([])->toBeEmpty();
|
||||||
|
expect(null)->toBeEmpty();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect([1, 2])->toBeEmpty();
|
||||||
|
expect(' ')->toBeEmpty();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect([])->not->toBeEmpty();
|
||||||
|
expect(null)->not->toBeEmpty();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toBeFalse.php
Normal file
15
tests/Features/Expect/toBeFalse.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('strict comparisons', function () {
|
||||||
|
expect(false)->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('')->toBeFalse();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(false)->not->toBe(false);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
23
tests/Features/Expect/toBeFile.php
Normal file
23
tests/Features/Expect/toBeFile.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
touch($this->tempFile = sys_get_temp_dir() . '/fake.file');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
unlink($this->tempFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect($this->tempFile)->toBeFile();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('/random/path/whatever.file')->toBeFile();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect($this->tempFile)->not->toBeFile();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeFloat.php
Normal file
16
tests/Features/Expect/toBeFloat.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(1.0)->toBeFloat();
|
||||||
|
expect(1)->not->toBeFloat();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(42)->toBeFloat();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(log(3))->not->toBeFloat();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeGreatherThan.php
Normal file
16
tests/Features/Expect/toBeGreatherThan.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('passes', function () {
|
||||||
|
expect(42)->toBeGreaterThan(41);
|
||||||
|
expect(4)->toBeGreaterThan(3.9);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(4)->toBeGreaterThan(4);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(5)->not->toBeGreaterThan(4);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeGreatherThanOrEqual.php
Normal file
16
tests/Features/Expect/toBeGreatherThanOrEqual.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('passes', function () {
|
||||||
|
expect(42)->toBeGreaterThanOrEqual(41);
|
||||||
|
expect(4)->toBeGreaterThanOrEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(4)->toBeGreaterThanOrEqual(4.1);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(5)->not->toBeGreaterThanOrEqual(5);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeInfinite.php
Normal file
16
tests/Features/Expect/toBeInfinite.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(log(0))->toBeInfinite();
|
||||||
|
expect(log(1))->not->toBeInfinite();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(asin(2))->toBeInfinite();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(INF)->not->toBeInfinite();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeInstanceOf.php
Normal file
16
tests/Features/Expect/toBeInstanceOf.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(new Exception())->toBeInstanceOf(Exception::class);
|
||||||
|
expect(new Exception())->not->toBeInstanceOf(RuntimeException::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(new Exception())->toBeInstanceOf(RuntimeException::class);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(new Exception())->not->toBeInstanceOf(Exception::class);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeInt.php
Normal file
16
tests/Features/Expect/toBeInt.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(42)->toBeInt();
|
||||||
|
expect(42.0)->not->toBeInt();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(42.0)->toBeInt();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(6 * 7)->not->toBeInt();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
23
tests/Features/Expect/toBeIterable.php
Normal file
23
tests/Features/Expect/toBeIterable.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect([])->toBeIterable();
|
||||||
|
expect(null)->not->toBeIterable();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(42)->toBeIterable();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
function gen(): iterable
|
||||||
|
{
|
||||||
|
yield 1;
|
||||||
|
yield 2;
|
||||||
|
yield 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(gen())->not->toBeIterable();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
17
tests/Features/Expect/toBeJson.php
Normal file
17
tests/Features/Expect/toBeJson.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect('{"hello":"world"}')->toBeJson();
|
||||||
|
expect('foo')->not->toBeJson();
|
||||||
|
expect('{"hello"')->not->toBeJson();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(':"world"}')->toBeJson();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('{"hello":"world"}')->not->toBeJson();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeLessThan.php
Normal file
16
tests/Features/Expect/toBeLessThan.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('passes', function () {
|
||||||
|
expect(41)->toBeLessThan(42);
|
||||||
|
expect(4)->toBeLessThan(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(4)->toBeLessThan(4);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(5)->not->toBeLessThan(6);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeLessThanOrEqual.php
Normal file
16
tests/Features/Expect/toBeLessThanOrEqual.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('passes', function () {
|
||||||
|
expect(41)->toBeLessThanOrEqual(42);
|
||||||
|
expect(4)->toBeLessThanOrEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(4)->toBeLessThanOrEqual(3.9);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(5)->not->toBeLessThanOrEqual(5);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeNAN.php
Normal file
16
tests/Features/Expect/toBeNAN.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(asin(2))->toBeNan();
|
||||||
|
expect(log(0))->not->toBeNan();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(1)->toBeNan();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(acos(1.5))->not->toBeNan();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeNull.php
Normal file
16
tests/Features/Expect/toBeNull.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(null)->toBeNull();
|
||||||
|
expect('')->not->toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('hello')->toBeNull();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(null)->not->toBeNull();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeNumeric.php
Normal file
16
tests/Features/Expect/toBeNumeric.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(42)->toBeNumeric();
|
||||||
|
expect('A')->not->toBeNumeric();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeNumeric();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(6 * 7)->not->toBeNumeric();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeObject.php
Normal file
16
tests/Features/Expect/toBeObject.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect((object) ['a' => 1])->toBeObject();
|
||||||
|
expect(['a' => 1])->not->toBeObject();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeObject();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect((object) 'ciao')->not->toBeObject();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toBeReadableDirectory.php
Normal file
15
tests/Features/Expect/toBeReadableDirectory.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(sys_get_temp_dir())->toBeReadableDirectory();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('/random/path/whatever')->toBeReadableDirectory();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(sys_get_temp_dir())->not->toBeReadableDirectory();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
23
tests/Features/Expect/toBeReadableFile.php
Normal file
23
tests/Features/Expect/toBeReadableFile.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
touch($this->tempFile = sys_get_temp_dir() . '/fake.file');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
unlink($this->tempFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect($this->tempFile)->toBeReadableFile();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('/random/path/whatever.file')->toBeReadableFile();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect($this->tempFile)->not->toBeReadableFile();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
22
tests/Features/Expect/toBeResource.php
Normal file
22
tests/Features/Expect/toBeResource.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
$resource = tmpfile();
|
||||||
|
|
||||||
|
afterAll(function () use ($resource) {
|
||||||
|
fclose($resource);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pass', function () use ($resource) {
|
||||||
|
expect($resource)->toBeResource();
|
||||||
|
expect(null)->not->toBeResource();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeResource();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () use ($resource) {
|
||||||
|
expect($resource)->not->toBeResource();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toBeScalar.php
Normal file
15
tests/Features/Expect/toBeScalar.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(1.1)->toBeScalar();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeScalar();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(42)->not->toBeScalar();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toBeString.php
Normal file
16
tests/Features/Expect/toBeString.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect('1.1')->toBeString();
|
||||||
|
expect(1.1)->not->toBeString();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(null)->toBeString();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('42')->not->toBeString();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toBeTrue.php
Normal file
15
tests/Features/Expect/toBeTrue.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('strict comparisons', function () {
|
||||||
|
expect(true)->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('')->toBeTrue();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(false)->not->toBe(false);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toBeWritableDirectory.php
Normal file
15
tests/Features/Expect/toBeWritableDirectory.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(sys_get_temp_dir())->toBeWritableDirectory();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('/random/path/whatever')->toBeWritableDirectory();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(sys_get_temp_dir())->not->toBeWritableDirectory();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
23
tests/Features/Expect/toBeWritableFile.php
Normal file
23
tests/Features/Expect/toBeWritableFile.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
touch($this->tempFile = sys_get_temp_dir() . '/fake.file');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
unlink($this->tempFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect($this->tempFile)->toBeWritableFile();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('/random/path/whatever.file')->toBeWritableFile();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect($this->tempFile)->not->toBeWritableFile();
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
19
tests/Features/Expect/toContain.php
Normal file
19
tests/Features/Expect/toContain.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('passes strings', function () {
|
||||||
|
expect([1, 2, 42])->toContain(42);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('passes arrays', function () {
|
||||||
|
expect('Nuno')->toContain('Nu');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect([1, 2, 42])->toContain(3);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect([1, 2, 42])->not->toContain(42);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toEndWith.php
Normal file
15
tests/Features/Expect/toEndWith.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect('username')->toEndWith('name');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('username')->toEndWith('password');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('username')->not->toEndWith('name');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toEqual.php
Normal file
15
tests/Features/Expect/toEqual.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect('00123')->toEqual(123);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(['a', 'b', 'c'])->toEqual(['a', 'b']);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('042')->not->toEqual(42);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toEqualCanonicalizing.php
Normal file
16
tests/Features/Expect/toEqualCanonicalizing.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect([1, 2, 3])->toEqualCanonicalizing([3, 1, 2]);
|
||||||
|
expect(['g', 'a', 'z'])->not->toEqualCanonicalizing(['a', 'z']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect([3, 2, 1])->toEqualCanonicalizing([1, 2]);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(['a', 'b', 'c'])->not->toEqualCanonicalizing(['b', 'a', 'c']);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toEqualWithDelta.php
Normal file
15
tests/Features/Expect/toEqualWithDelta.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(1.0)->toEqualWithDelta(1.3, .4);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(1.0)->toEqualWithDelta(1.5, .1);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(1.0)->not->toEqualWithDelta(1.6, .7);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toHaveCount.php
Normal file
15
tests/Features/Expect/toHaveCount.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect([1, 2, 3])->toHaveCount(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect([1, 2, 3])->toHaveCount(4);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect([1, 2, 3])->not->toHaveCount(3);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toHaveKey.php
Normal file
15
tests/Features/Expect/toHaveKey.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKey('c');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKey('hello');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(['a' => 1, 'hello' => 'world', 'c'])->not->toHaveKey('hello');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toHaveKeys.php
Normal file
15
tests/Features/Expect/toHaveKeys.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKeys(['a', 'c']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKeys(['a', 'd']);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(['a' => 1, 'hello' => 'world', 'c'])->not->toHaveKeys(['hello', 'c']);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
22
tests/Features/Expect/toHaveProperty.php
Normal file
22
tests/Features/Expect/toHaveProperty.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->foo = 'bar';
|
||||||
|
$obj->fooNull = null;
|
||||||
|
|
||||||
|
test('pass', function () use ($obj) {
|
||||||
|
expect($obj)->toHaveProperty('foo');
|
||||||
|
expect($obj)->toHaveProperty('foo', 'bar');
|
||||||
|
expect($obj)->toHaveProperty('fooNull');
|
||||||
|
expect($obj)->toHaveProperty('fooNull', null);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () use ($obj) {
|
||||||
|
expect($obj)->toHaveProperty('bar');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () use ($obj) {
|
||||||
|
expect($obj)->not->toHaveProperty('foo');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toMatch.php
Normal file
15
tests/Features/Expect/toMatch.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect('Hello World')->toMatch('/^hello wo.*$/i');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('Hello World')->toMatch('/^hello$/i');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('Hello World')->not->toMatch('/^hello wo.*$/i');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
31
tests/Features/Expect/toMatchArray.php
Normal file
31
tests/Features/Expect/toMatchArray.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->user = [
|
||||||
|
'id' => 1,
|
||||||
|
'name' => 'Nuno',
|
||||||
|
'email' => 'enunomaduro@gmail.com',
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect($this->user)->toMatchArray([
|
||||||
|
'name' => 'Nuno',
|
||||||
|
'email' => 'enunomaduro@gmail.com',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect($this->user)->toMatchArray([
|
||||||
|
'name' => 'Not the same name',
|
||||||
|
'email' => 'enunomaduro@gmail.com',
|
||||||
|
]);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect($this->user)->not->toMatchArray([
|
||||||
|
'id' => 1,
|
||||||
|
]);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
16
tests/Features/Expect/toMatchConstraint.php
Normal file
16
tests/Features/Expect/toMatchConstraint.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\Constraint\IsTrue;
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect(true)->toMatchConstraint(new IsTrue());
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect(false)->toMatchConstraint(new IsTrue());
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect(true)->not->toMatchConstraint(new IsTrue());
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
31
tests/Features/Expect/toMatchObject.php
Normal file
31
tests/Features/Expect/toMatchObject.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
$this->user = (object) [
|
||||||
|
'id' => 1,
|
||||||
|
'name' => 'Nuno',
|
||||||
|
'email' => 'enunomaduro@gmail.com',
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect($this->user)->toMatchObject([
|
||||||
|
'name' => 'Nuno',
|
||||||
|
'email' => 'enunomaduro@gmail.com',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect($this->user)->toMatchObject([
|
||||||
|
'name' => 'Not the same name',
|
||||||
|
'email' => 'enunomaduro@gmail.com',
|
||||||
|
]);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect($this->user)->not->toMatchObject([
|
||||||
|
'id' => 1,
|
||||||
|
]);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
15
tests/Features/Expect/toStartWith.php
Normal file
15
tests/Features/Expect/toStartWith.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
|
test('pass', function () {
|
||||||
|
expect('username')->toStartWith('user');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('failures', function () {
|
||||||
|
expect('username')->toStartWith('password');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () {
|
||||||
|
expect('username')->not->toStartWith('user');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
Reference in New Issue
Block a user