diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 2617fea4..c1ad83dc 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 ee4e7231..3c9bb881 100644 --- a/src/Support/Str.php +++ b/src/Support/Str.php @@ -92,4 +92,12 @@ 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; + } } diff --git a/tests/Features/Expect/toBeUUID.php b/tests/Features/Expect/toBeUUID.php new file mode 100644 index 00000000..c77d6bb4 --- /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(); +});