mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 15:57:21 +01:00
Reimplements the new toHaveArray features.
This commit is contained in:
@ -6,8 +6,10 @@ namespace Pest;
|
|||||||
|
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
use Pest\Concerns\Extendable;
|
use Pest\Concerns\Extendable;
|
||||||
|
use Pest\Support\Arr;
|
||||||
use PHPUnit\Framework\Assert;
|
use PHPUnit\Framework\Assert;
|
||||||
use PHPUnit\Framework\Constraint\Constraint;
|
use PHPUnit\Framework\Constraint\Constraint;
|
||||||
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
use SebastianBergmann\Exporter\Exporter;
|
use SebastianBergmann\Exporter\Exporter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -522,10 +524,16 @@ final class Expectation
|
|||||||
$array = (array) $this->value;
|
$array = (array) $this->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert::assertArrayHasKey($key, $array);
|
try {
|
||||||
|
Assert::assertTrue(Arr::has($array, $key));
|
||||||
|
|
||||||
|
/* @phpstan-ignore-next-line */
|
||||||
|
} catch (ExpectationFailedException $exception) {
|
||||||
|
throw new ExpectationFailedException("Failed asserting that an array has the key '$key'", $exception->getComparisonFailure());
|
||||||
|
}
|
||||||
|
|
||||||
if (func_num_args() > 1) {
|
if (func_num_args() > 1) {
|
||||||
Assert::assertEquals($value, $array[$key]);
|
Assert::assertEquals($value, Arr::get($array, $key));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
|||||||
68
src/Support/Arr.php
Normal file
68
src/Support/Arr.php
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Pest\Support;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Credits: most of this class methods and implementations
|
||||||
|
* belongs to the Arr helper of laravel/framework project
|
||||||
|
* (https://github.com/laravel/framework).
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class Arr
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<mixed> $array
|
||||||
|
* @param string|int $key
|
||||||
|
*/
|
||||||
|
public static function has(array $array, $key): bool
|
||||||
|
{
|
||||||
|
$key = (string) $key;
|
||||||
|
|
||||||
|
if (array_key_exists($key, $array)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (explode('.', $key) as $segment) {
|
||||||
|
if (is_array($array) && array_key_exists($segment, $array)) {
|
||||||
|
$array = $array[$segment];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<mixed> $array
|
||||||
|
* @param string|int $key
|
||||||
|
* @param null $default
|
||||||
|
*
|
||||||
|
* @return array|mixed|null
|
||||||
|
*/
|
||||||
|
public static function get(array $array, $key, $default = null)
|
||||||
|
{
|
||||||
|
$key = (string) $key;
|
||||||
|
|
||||||
|
if (array_key_exists($key, $array)) {
|
||||||
|
return $array[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($key, '.') === false) {
|
||||||
|
return $array[$key] ?? $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (explode('.', $key) as $segment) {
|
||||||
|
if (is_array($array) && array_key_exists($segment, $array)) {
|
||||||
|
$array = $array[$segment];
|
||||||
|
} else {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -336,8 +336,23 @@
|
|||||||
|
|
||||||
PASS Tests\Features\Expect\toHaveKey
|
PASS Tests\Features\Expect\toHaveKey
|
||||||
✓ pass
|
✓ pass
|
||||||
|
✓ pass with nested key
|
||||||
|
✓ pass with plain key with dots
|
||||||
|
✓ pass with value check
|
||||||
|
✓ pass with value check and nested key
|
||||||
|
✓ pass with value check and plain key with dots
|
||||||
✓ failures
|
✓ failures
|
||||||
|
✓ failures with nested key
|
||||||
|
✓ failures with plain key with dots
|
||||||
|
✓ fails with wrong value
|
||||||
|
✓ fails with wrong value and nested key
|
||||||
|
✓ fails with wrong value and plain key with dots
|
||||||
✓ not failures
|
✓ not failures
|
||||||
|
✓ not failures with nested key
|
||||||
|
✓ not failures with plain key with dots
|
||||||
|
✓ not failures with correct value
|
||||||
|
✓ not failures with correct value and with nested key
|
||||||
|
✓ not failures with correct value and with plain key with dots
|
||||||
|
|
||||||
PASS Tests\Features\Expect\toHaveKeys
|
PASS Tests\Features\Expect\toHaveKeys
|
||||||
✓ pass
|
✓ pass
|
||||||
@ -554,5 +569,5 @@
|
|||||||
✓ it is a test
|
✓ it is a test
|
||||||
✓ it uses correct parent class
|
✓ it uses correct parent class
|
||||||
|
|
||||||
Tests: 4 incompleted, 7 skipped, 340 passed
|
Tests: 4 incompleted, 7 skipped, 355 passed
|
||||||
|
|
||||||
@ -2,14 +2,68 @@
|
|||||||
|
|
||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
test('pass', function () {
|
$test_array = [
|
||||||
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKey('c');
|
'a' => 1,
|
||||||
});
|
'b',
|
||||||
|
'c' => 'world',
|
||||||
|
'd' => [
|
||||||
|
'e' => 'hello',
|
||||||
|
],
|
||||||
|
'key.with.dots' => false,
|
||||||
|
];
|
||||||
|
|
||||||
test('failures', function () {
|
test('pass')->expect($test_array)->toHaveKey('c');
|
||||||
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKey('hello');
|
test('pass with nested key')->expect($test_array)->toHaveKey('d.e');
|
||||||
|
test('pass with plain key with dots')->expect($test_array)->toHaveKey('key.with.dots');
|
||||||
|
|
||||||
|
test('pass with value check')->expect($test_array)->toHaveKey('c', 'world');
|
||||||
|
test('pass with value check and nested key')->expect($test_array)->toHaveKey('d.e', 'hello');
|
||||||
|
test('pass with value check and plain key with dots')->expect($test_array)->toHaveKey('key.with.dots', false);
|
||||||
|
|
||||||
|
test('failures', function () use ($test_array) {
|
||||||
|
expect($test_array)->toHaveKey('foo');
|
||||||
|
})->throws(ExpectationFailedException::class, "Failed asserting that an array has the key 'foo'");
|
||||||
|
|
||||||
|
test('failures with nested key', function () use ($test_array) {
|
||||||
|
expect($test_array)->toHaveKey('d.bar');
|
||||||
|
})->throws(ExpectationFailedException::class, "Failed asserting that an array has the key 'd.bar'");
|
||||||
|
|
||||||
|
test('failures with plain key with dots', function () use ($test_array) {
|
||||||
|
expect($test_array)->toHaveKey('missing.key.with.dots');
|
||||||
|
})->throws(ExpectationFailedException::class, "Failed asserting that an array has the key 'missing.key.with.dots'");
|
||||||
|
|
||||||
|
test('fails with wrong value', function () use ($test_array) {
|
||||||
|
expect($test_array)->toHaveKey('c', 'bar');
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
test('not failures', function () {
|
test('fails with wrong value and nested key', function () use ($test_array) {
|
||||||
expect(['a' => 1, 'hello' => 'world', 'c'])->not->toHaveKey('hello');
|
expect($test_array)->toHaveKey('d.e', 'foo');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('fails with wrong value and plain key with dots', function () use ($test_array) {
|
||||||
|
expect($test_array)->toHaveKey('key.with.dots', true);
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures', function () use ($test_array) {
|
||||||
|
expect($test_array)->not->toHaveKey('c');
|
||||||
|
})->throws(ExpectationFailedException::class, "Expecting Array (...) not to have key 'c'");
|
||||||
|
|
||||||
|
test('not failures with nested key', function () use ($test_array) {
|
||||||
|
expect($test_array)->not->toHaveKey('d.e');
|
||||||
|
})->throws(ExpectationFailedException::class, "Expecting Array (...) not to have key 'd.e'");
|
||||||
|
|
||||||
|
test('not failures with plain key with dots', function () use ($test_array) {
|
||||||
|
expect($test_array)->not->toHaveKey('key.with.dots');
|
||||||
|
})->throws(ExpectationFailedException::class, "Expecting Array (...) not to have key 'key.with.dots'");
|
||||||
|
|
||||||
|
test('not failures with correct value', function () use ($test_array) {
|
||||||
|
expect($test_array)->not->toHaveKey('c', 'world');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures with correct value and with nested key', function () use ($test_array) {
|
||||||
|
expect($test_array)->not->toHaveKey('d.e', 'hello');
|
||||||
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
|
test('not failures with correct value and with plain key with dots', function () use ($test_array) {
|
||||||
|
expect($test_array)->not->toHaveKey('key.with.dots', false);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
|
|
||||||
test('pass', function () {
|
test('pass', function () {
|
||||||
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKeys(['a', 'c']);
|
expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => 'baz']])->toHaveKeys(['a', 'c', 'foo.bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('failures', function () {
|
test('failures', function () {
|
||||||
expect(['a' => 1, 'b', 'c' => 'world'])->toHaveKeys(['a', 'd']);
|
expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => 'baz']])->toHaveKeys(['a', 'd', 'foo.bar', 'hello.world']);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|
||||||
test('not failures', function () {
|
test('not failures', function () {
|
||||||
expect(['a' => 1, 'hello' => 'world', 'c'])->not->toHaveKeys(['hello', 'c']);
|
expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => 'baz']])->not->toHaveKeys(['foo.bar', 'c', 'z']);
|
||||||
})->throws(ExpectationFailedException::class);
|
})->throws(ExpectationFailedException::class);
|
||||||
|
|||||||
Reference in New Issue
Block a user