diff --git a/src/Expectation.php b/src/Expectation.php index 148e44b1..c5f4c411 100644 --- a/src/Expectation.php +++ b/src/Expectation.php @@ -762,4 +762,26 @@ final class Expectation return $this; } + + /** + * Asserts that the given expectation is iterable and contains kebab-case keys. + * + * @return self + */ + public function toHaveKebabCaseKeys(string $message = ''): self + { + if (! is_iterable($this->value)) { + InvalidExpectationValue::expected('iterable'); + } + + foreach ($this->value as $k => $item) { + $this->and($k)->toBeKebabCase($message); + + if (is_array($item)) { + $this->and($item)->toHaveKebabCaseKeys($message); + } + } + + return $this; + } } diff --git a/tests/Features/Expect/toHaveKebabCaseKeys.php b/tests/Features/Expect/toHaveKebabCaseKeys.php new file mode 100644 index 00000000..cb16bc93 --- /dev/null +++ b/tests/Features/Expect/toHaveKebabCaseKeys.php @@ -0,0 +1,31 @@ + true, + 'kebab-case' => [ + 'kebab' => true, + 'kebab-case' => [ + 'kebab' => true, + 'kebab-case' => true, + ], + ], +]; + +test('pass', function () use ($array) { + expect($array)->toHaveKebabCaseKeys(); +}); + +test('failures', function () { + expect('not-an-array')->toHaveKebabCaseKeys(); +})->throws(InvalidExpectationValue::class); + +test('failures with message', function () use ($array) { + expect($array)->not->toHaveKebabCaseKeys('oh no!'); +})->throws(ExpectationFailedException::class, 'oh no!'); + +test('not failures', function () use ($array) { + expect($array)->not->toHaveKebabCaseKeys(); +})->throws(ExpectationFailedException::class);