diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 400095f9..88506e58 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -16,6 +16,7 @@ use Pest\Matchers\Any; use Pest\Support\Arr; use Pest\Support\Exporter; use Pest\Support\NullClosure; +use Pest\Support\Str; use Pest\TestSuite; use PHPUnit\Framework\Assert; use PHPUnit\Framework\Constraint\Constraint; @@ -1111,4 +1112,20 @@ final class Expectation return $this; } + + /** + * Asserts that the value is UUID. + * + * @return self + */ + public function toBeUuid(string $message = ''): self + { + if (! is_string($this->value)) { + InvalidExpectationValue::expected('string'); + } + + Assert::assertTrue(Str::isUuid($this->value), $message); + + return $this; + } } diff --git a/src/Support/Str.php b/src/Support/Str.php index c0c5a51b..0f2dc63a 100644 --- a/src/Support/Str.php +++ b/src/Support/Str.php @@ -93,6 +93,14 @@ final class Str return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0]; } + /** + * Determine if a given value is a valid UUID. + */ + public static function isUuid(string $value): bool + { + return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0; + } + /** * Creates a describe block as `$describeDescription` → `$testDescription` format. */ diff --git a/tests/Features/Expect/toBeUuid.php b/tests/Features/Expect/toBeUuid.php new file mode 100644 index 00000000..971a196a --- /dev/null +++ b/tests/Features/Expect/toBeUuid.php @@ -0,0 +1,31 @@ +toBeUuid(); +})->throws(InvalidExpectationValue::class, 'Invalid expectation value type. Expected [string].'); + +test('pass', function () { + expect('3cafb226-4326-11ee-a516-846993788c86')->toBeUuid(); // version 1 + expect('0000415c-4326-21ee-a700-846993788c86')->toBeUuid(); // version 2 + expect('3f703955-aaba-3e70-a3cb-baff6aa3b28f')->toBeUuid(); // version 3 + expect('ca0a8228-cdf6-41db-b34b-c2f31485796c')->toBeUuid(); // version 4 + expect('a35477ae-bfb1-5f2e-b5a4-4711594d855f')->toBeUuid(); // version 5 + expect('1ee43263-cf5a-6fd8-8f47-846993788c86')->toBeUuid(); // version 6 + expect('018a2bef-09f2-728c-becb-c3f569d91486')->toBeUuid(); // version 7 + expect('00112233-4455-8677-8899-aabbccddeeff')->toBeUuid(); // version 8 +}); + +test('failures', function () { + expect('foo')->toBeUuid(); +})->throws(ExpectationFailedException::class); + +test('failures with message', function () { + expect('bar')->toBeUuid('oh no!'); +})->throws(ExpectationFailedException::class, 'oh no!'); + +test('not failures', function () { + expect('foo')->not->toBeUuid(); +});