From 77b7181b08abb2a55050ab8d3a0e12e58ef23ba7 Mon Sep 17 00:00:00 2001 From: Francescu Garoby Date: Fri, 29 Apr 2022 09:54:12 +0200 Subject: [PATCH 1/3] Make 'toHaveKeys' accept multi-dimensional associative arrays --- src/Expectations/OppositeExpectation.php | 11 ++++++++--- src/Mixins/Expectation.php | 10 +++++++--- src/Support/Arr.php | 22 ++++++++++++++++++++++ tests/Features/Expect/toHaveKeys.php | 12 ++++++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index 1ae9ccbe..636405ac 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Pest\Expectations; use Pest\Expectation; +use Pest\Support\Arr; use PHPUnit\Framework\ExpectationFailedException; use SebastianBergmann\Exporter\Exporter; @@ -29,15 +30,19 @@ final class OppositeExpectation /** * Asserts that the value array not has the provided $keys. * - * @param array $keys + * @param array $keys * * @return Expectation */ public function toHaveKeys(array $keys): Expectation { - foreach ($keys as $key) { + foreach ($keys as $k => $key) { try { - $this->original->toHaveKey($key); + if (is_array($key)) { + $this->toHaveKeys(array_keys(Arr::dot($key, $k . '.'))); + } else { + $this->original->toHaveKey($key); + } } catch (ExpectationFailedException) { continue; } diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 337cc9cc..72978ce6 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -595,14 +595,18 @@ final class Expectation /** * Asserts that the value array has the provided $keys. * - * @param array $keys + * @param array $keys * * @return Expectation */ public function toHaveKeys(array $keys): Expectation { - foreach ($keys as $key) { - $this->toHaveKey($key); + foreach ($keys as $k => $key) { + if (is_array($key)) { + $this->toHaveKeys(array_keys(Arr::dot($key, $k . '.'))); + } else { + $this->toHaveKey($key); + } } return $this; diff --git a/src/Support/Arr.php b/src/Support/Arr.php index 922110e1..f4eb19e2 100644 --- a/src/Support/Arr.php +++ b/src/Support/Arr.php @@ -60,4 +60,26 @@ final class Arr return $array; } + + /** + * Flatten a multi-dimensional associative array with dots. + * + * @param array $array + * + * @return array + */ + public static function dot(array $array, string $prepend = ''): array + { + $results = []; + + foreach ($array as $key => $value) { + if (is_array($value) && count($value) > 0) { + $results = array_merge($results, static::dot($value, $prepend . $key . '.')); + } else { + $results[$prepend . $value] = $value; + } + } + + return $results; + } } diff --git a/tests/Features/Expect/toHaveKeys.php b/tests/Features/Expect/toHaveKeys.php index 4c29a431..6ab0f506 100644 --- a/tests/Features/Expect/toHaveKeys.php +++ b/tests/Features/Expect/toHaveKeys.php @@ -6,10 +6,22 @@ test('pass', function () { expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => 'baz']])->toHaveKeys(['a', 'c', 'foo.bar']); }); +test('pass with multi-dimensional arrays', function () { + expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => ['bir' => 'biz']]])->toHaveKeys(['a', 'c', 'foo' => ['bar' => ['bir']]]); +}); + test('failures', function () { expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => 'baz']])->toHaveKeys(['a', 'd', 'foo.bar', 'hello.world']); })->throws(ExpectationFailedException::class); +test('failures with multi-dimensional arrays', function () { + expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => ['bir' => 'biz']]])->toHaveKeys(['a', 'd', 'foo' => ['bar' => 'bir'], 'hello.world']); +})->throws(ExpectationFailedException::class); + test('not failures', function () { expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => 'baz']])->not->toHaveKeys(['foo.bar', 'c', 'z']); })->throws(ExpectationFailedException::class); + +test('not failures with multi-dimensional arrays', function () { + expect(['a' => 1, 'b', 'c' => 'world', 'foo' => ['bar' => ['bir' => 'biz']]])->not->toHaveKeys(['foo' => ['bar' => 'bir'], 'c', 'z']); +})->throws(ExpectationFailedException::class); From 949ba1f29866705113ff8d9e6e4a67d170053509 Mon Sep 17 00:00:00 2001 From: Francescu Garoby Date: Fri, 29 Apr 2022 23:06:29 +0200 Subject: [PATCH 2/3] fix PHPStan types --- src/Expectations/OppositeExpectation.php | 2 +- src/Mixins/Expectation.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index 636405ac..55893bf4 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -30,7 +30,7 @@ final class OppositeExpectation /** * Asserts that the value array not has the provided $keys. * - * @param array $keys + * @param array> $keys * * @return Expectation */ diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 72978ce6..d6f4eb35 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -595,7 +595,7 @@ final class Expectation /** * Asserts that the value array has the provided $keys. * - * @param array $keys + * @param array> $keys * * @return Expectation */ From 1e86dcecd0fb5986e01496a049f36b41ec25214d Mon Sep 17 00:00:00 2001 From: Francescu Garoby Date: Sat, 30 Apr 2022 11:08:42 +0200 Subject: [PATCH 3/3] Better PHPStan types --- src/Expectations/OppositeExpectation.php | 2 +- src/Mixins/Expectation.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Expectations/OppositeExpectation.php b/src/Expectations/OppositeExpectation.php index 55893bf4..a5b9b480 100644 --- a/src/Expectations/OppositeExpectation.php +++ b/src/Expectations/OppositeExpectation.php @@ -30,7 +30,7 @@ final class OppositeExpectation /** * Asserts that the value array not has the provided $keys. * - * @param array> $keys + * @param array> $keys * * @return Expectation */ diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index d6f4eb35..71316264 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -595,7 +595,7 @@ final class Expectation /** * Asserts that the value array has the provided $keys. * - * @param array> $keys + * @param array> $keys * * @return Expectation */