Matching.php
TLDR
The provided file, located at src/Illuminate/Testing/Fluent/Concerns/Matching.php
, contains a trait called Matching
that provides several methods for asserting properties in testing.
Methods
where(string $key, $expected): self
This method asserts that a property matches the expected value. It takes a string $key
representing the property name, and $expected
which can be a value or a closure that returns a boolean value. If the property is an array, it will be converted to a Collection
. It then compares the expected and actual values using assertSame()
.
whereNot(string $key, $expected): self
This method asserts that a property does not match the expected value. It takes a string $key
representing the property name, and $expected
which can be a value or a closure that returns a boolean value. If the property is an array, it will be converted to a Collection
. It then compares the expected and actual values using assertNotSame()
.
whereAll(array $bindings): self
This method asserts that all properties match their expected values. It takes an array $bindings
where the keys represent the property names and the values represent the expected values. It calls the where()
method for each property-value pair.
whereType(string $key, $expected): self
This method asserts that a property is of the expected type. It takes a string $key
representing the property name, and $expected
which can be a string or an array of expected type(s). It compares the actual property type to the expected type(s) using assertContains()
.
whereAllType(array $bindings): self
This method asserts that all properties are of their expected types. It takes an array $bindings
where the keys represent the property names and the values represent the expected types. It calls the whereType()
method for each property-type pair.
whereContains(string $key, $expected)
This method asserts that a property contains the expected values. It takes a string $key
representing the property name, and $expected
which can be a single value or an array of expected values. It checks if the property (as a Collection
) contains any of the expected values using containsStrict()
. It then uses assertEmpty()
to check if any values are missing.
ensureSorted(&$value): void
This protected method ensures that all properties are sorted in the same way, recursively. It takes a reference to a variable $value
and recursively sorts the nested arrays using ksort()
.
END
<?php
namespace Illuminate\Testing\Fluent\Concerns;
use Closure;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Collection;
use PHPUnit\Framework\Assert as PHPUnit;
trait Matching
{
/**
* Asserts that the property matches the expected value.
*
* @param string $key
* @param mixed|\Closure $expected
* @return $this
*/
public function where(string $key, $expected): self
{
$this->has($key);
$actual = $this->prop($key);
if ($expected instanceof Closure) {
PHPUnit::assertTrue(
$expected(is_array($actual) ? Collection::make($actual) : $actual),
sprintf('Property [%s] was marked as invalid using a closure.', $this->dotPath($key))
);
return $this;
}
if ($expected instanceof Arrayable) {
$expected = $expected->toArray();
}
$this->ensureSorted($expected);
$this->ensureSorted($actual);
PHPUnit::assertSame(
$expected,
$actual,
sprintf('Property [%s] does not match the expected value.', $this->dotPath($key))
);
return $this;
}
/**
* Asserts that the property does not match the expected value.
*
* @param string $key
* @param mixed|\Closure $expected
* @return $this
*/
public function whereNot(string $key, $expected): self
{
$this->has($key);
$actual = $this->prop($key);
if ($expected instanceof Closure) {
PHPUnit::assertFalse(
$expected(is_array($actual) ? Collection::make($actual) : $actual),
sprintf('Property [%s] was marked as invalid using a closure.', $this->dotPath($key))
);
return $this;
}
if ($expected instanceof Arrayable) {
$expected = $expected->toArray();
}
$this->ensureSorted($expected);
$this->ensureSorted($actual);
PHPUnit::assertNotSame(
$expected,
$actual,
sprintf(
'Property [%s] contains a value that should be missing: [%s, %s]',
$this->dotPath($key),
$key,
$expected
)
);
return $this;
}
/**
* Asserts that all properties match their expected values.
*
* @param array $bindings
* @return $this
*/
public function whereAll(array $bindings): self
{
foreach ($bindings as $key => $value) {
$this->where($key, $value);
}
return $this;
}
/**
* Asserts that the property is of the expected type.
*
* @param string $key
* @param string|array $expected
* @return $this
*/
public function whereType(string $key, $expected): self
{
$this->has($key);
$actual = $this->prop($key);
if (! is_array($expected)) {
$expected = explode('|', $expected);
}
PHPUnit::assertContains(
strtolower(gettype($actual)),
$expected,
sprintf('Property [%s] is not of expected type [%s].', $this->dotPath($key), implode('|', $expected))
);
return $this;
}
/**
* Asserts that all properties are of their expected types.
*
* @param array $bindings
* @return $this
*/
public function whereAllType(array $bindings): self
{
foreach ($bindings as $key => $value) {
$this->whereType($key, $value);
}
return $this;
}
/**
* Asserts that the property contains the expected values.
*
* @param string $key
* @param mixed $expected
* @return $this
*/
public function whereContains(string $key, $expected)
{
$actual = Collection::make(
$this->prop($key) ?? $this->prop()
);
$missing = Collection::make($expected)->reject(function ($search) use ($key, $actual) {
if ($actual->containsStrict($key, $search)) {
return true;
}
return $actual->containsStrict($search);
});
if ($missing->whereInstanceOf('Closure')->isNotEmpty()) {
PHPUnit::assertEmpty(
$missing->toArray(),
sprintf(
'Property [%s] does not contain a value that passes the truth test within the given closure.',
$key,
)
);
} else {
PHPUnit::assertEmpty(
$missing->toArray(),
sprintf(
'Property [%s] does not contain [%s].',
$key,
implode(', ', array_values($missing->toArray()))
)
);
}
return $this;
}
/**
* Ensures that all properties are sorted the same way, recursively.
*
* @param mixed $value
* @return void
*/
protected function ensureSorted(&$value): void
{
if (! is_array($value)) {
return;
}
foreach ($value as &$arg) {
$this->ensureSorted($arg);
}
ksort($value);
}
/**
* Compose the absolute "dot" path to the given key.
*
* @param string $key
* @return string
*/
abstract protected function dotPath(string $key = ''): string;
/**
* Ensure that the given prop exists.
*
* @param string $key
* @param null $value
* @param \Closure|null $scope
* @return $this
*/
abstract public function has(string $key, $value = null, Closure $scope = null);
/**
* Retrieve a prop within the current scope using "dot" notation.
*
* @param string|null $key
* @return mixed
*/
abstract protected function prop(string $key = null);
}