diff --git a/docs/migrating-from-v2-to-v3.md b/docs/migrating-from-v2-to-v3.md index 1b48c33f3..d2b03667f 100644 --- a/docs/migrating-from-v2-to-v3.md +++ b/docs/migrating-from-v2-to-v3.md @@ -156,6 +156,39 @@ These validators have been replaced by `DateTimeDiff`, which provides more flexi + v::dateTimeDiff('years', v::between(18, 65))->assert($birthDate); ``` +##### `PrimeNumber`, `Fibonacci`, `PerfectSquare` + +Combine `Callback` with a mathematical library of your choice: + +```diff +- v::primeNumber()->assert(7); ++ v::callback(static fn ($input) => \MathPHP\NumberTheory\Integer::isPrime($input))->assert(7); +``` + +See: https://github.com/markrogoyski/math-php + +##### `FilterVar` + +Use `Callback` instead: + +```diff +- v::filterVar(FILTER_VALIDATE_INT)->assert(123); ++ v::callback(static fn($input) => filter_var($input, FILTER_VALIDATE_INT) !== false)->assert(123); +``` + +##### `Uploaded` + +Use `Callback` instead: + +```diff +- v::uploaded()->assert($fileName); ++ v::callback('is_uploaded_file')->assert($fileName); +``` + +##### `VideoUrl` + +We offer no recommendation for replacing this validator. + #### Behavior changes ##### `Attribute` replaced by `Property` variants diff --git a/docs/validators.md b/docs/validators.md index 287fa7af4..1d8cce3ab 100644 --- a/docs/validators.md +++ b/docs/validators.md @@ -25,27 +25,27 @@ In this page you will find a list of validators by their category. **Date and Time**: [Date][] - [DateTime][] - [DateTimeDiff][] - [LeapDate][] - [LeapYear][] - [Time][] -**File system**: [Directory][] - [Executable][] - [Exists][] - [Extension][] - [File][] - [Image][] - [Mimetype][] - [Readable][] - [Size][] - [SymbolicLink][] - [Uploaded][] - [Writable][] +**File system**: [Directory][] - [Executable][] - [Exists][] - [Extension][] - [File][] - [Image][] - [Mimetype][] - [Readable][] - [Size][] - [SymbolicLink][] - [Writable][] **ISO codes**: [CountryCode][] - [CurrencyCode][] - [LanguageCode][] - [SubdivisionCode][] **Identifications**: [Bsn][] - [Cnh][] - [Cnpj][] - [Cpf][] - [Hetu][] - [Imei][] - [Isbn][] - [Luhn][] - [MacAddress][] - [NfeAccessKey][] - [Nif][] - [Nip][] - [Pesel][] - [Pis][] - [PolishIdCard][] - [PortugueseNif][] -**Internet**: [Domain][] - [Email][] - [Ip][] - [PublicDomainSuffix][] - [Tld][] - [Url][] - [VideoUrl][] +**Internet**: [Domain][] - [Email][] - [Ip][] - [PublicDomainSuffix][] - [Tld][] - [Url][] **Localization**: [CountryCode][] - [CurrencyCode][] - [LanguageCode][] - [PostalCode][] - [SubdivisionCode][] -**Math**: [Factor][] - [Fibonacci][] - [Finite][] - [Infinite][] - [Multiple][] - [Negative][] - [PerfectSquare][] - [Positive][] - [PrimeNumber][] +**Math**: [Factor][] - [Finite][] - [Infinite][] - [Multiple][] - [Negative][] - [Positive][] -**Miscellaneous**: [Blank][] - [Falsy][] - [FilterVar][] - [Named][] - [Templated][] - [Undef][] +**Miscellaneous**: [Blank][] - [Falsy][] - [Named][] - [Templated][] - [Undef][] **Nesting**: [AllOf][] - [AnyOf][] - [Call][] - [Circuit][] - [Each][] - [Key][] - [KeySet][] - [Lazy][] - [NoneOf][] - [Not][] - [NullOr][] - [OneOf][] - [Property][] - [PropertyOptional][] - [UndefOr][] - [When][] -**Numbers**: [Base][] - [Decimal][] - [Digit][] - [Even][] - [Factor][] - [Fibonacci][] - [Finite][] - [FloatType][] - [FloatVal][] - [Infinite][] - [IntType][] - [IntVal][] - [Multiple][] - [Negative][] - [Number][] - [NumericVal][] - [Odd][] - [PerfectSquare][] - [Positive][] - [PrimeNumber][] - [Roman][] +**Numbers**: [Base][] - [Decimal][] - [Digit][] - [Even][] - [Factor][] - [Finite][] - [FloatType][] - [FloatVal][] - [Infinite][] - [IntType][] - [IntVal][] - [Multiple][] - [Negative][] - [Number][] - [NumericVal][] - [Odd][] - [Positive][] - [Roman][] **Objects**: [Attributes][] - [Instance][] - [ObjectType][] - [Property][] - [PropertyExists][] - [PropertyOptional][] -**Strings**: [Alnum][] - [Alpha][] - [Base64][] - [Charset][] - [Consonant][] - [Contains][] - [ContainsAny][] - [ContainsCount][] - [Control][] - [Digit][] - [Emoji][] - [EndsWith][] - [Graph][] - [HexRgbColor][] - [In][] - [Json][] - [Lowercase][] - [Phone][] - [PhpLabel][] - [PostalCode][] - [Printable][] - [Punct][] - [Regex][] - [Slug][] - [Sorted][] - [Space][] - [Spaced][] - [StartsWith][] - [StringType][] - [StringVal][] - [Uppercase][] - [Uuid][] - [Version][] - [Vowel][] - [Xdigit][] +**Strings**: [Alnum][] - [Alpha][] - [Base64][] - [Charset][] - [Consonant][] - [Contains][] - [ContainsAny][] - [ContainsCount][] - [Control][] - [Digit][] - [Emoji][] - [EndsWith][] - [Graph][] - [HexRgbColor][] - [In][] - [Json][] - [Lowercase][] - [Phone][] - [PostalCode][] - [Printable][] - [Punct][] - [Regex][] - [Slug][] - [Sorted][] - [Space][] - [Spaced][] - [StartsWith][] - [StringType][] - [StringVal][] - [Uppercase][] - [Uuid][] - [Version][] - [Vowel][] - [Xdigit][] **Structures**: [Attributes][] - [Key][] - [KeyExists][] - [KeyOptional][] - [KeySet][] - [Named][] - [Property][] - [PropertyExists][] - [PropertyOptional][] - [Templated][] @@ -110,9 +110,7 @@ In this page you will find a list of validators by their category. - [Factor][] - `v::factor(0)->assert(5);` - [FalseVal][] - `v::falseVal()->assert(false);` - [Falsy][] - `v::falsy()->assert('');` -- [Fibonacci][] - `v::fibonacci()->assert(1);` - [File][] - `v::file()->assert(__FILE__);` -- [FilterVar][] - `v::filterVar(FILTER_VALIDATE_EMAIL)->assert('bob@example.com');` - [Finite][] - `v::finite()->assert('10');` - [FloatType][] - `v::floatType()->assert(1.5);` - [FloatVal][] - `v::floatVal()->assert(1.5);` @@ -167,16 +165,13 @@ In this page you will find a list of validators by their category. - [ObjectType][] - `v::objectType()->assert(new stdClass);` - [Odd][] - `v::odd()->assert(3);` - [OneOf][] - `v::oneOf(v::digit(), v::alpha())->assert('AB');` -- [PerfectSquare][] - `v::perfectSquare()->assert(25); // (5*5)` - [Pesel][] - `v::pesel()->assert('21120209256');` - [Phone][] - `v::phone()->assert('+1 650 253 00 00');` -- [PhpLabel][] - `v::phpLabel()->assert('person'); //true` - [Pis][] - `v::pis()->assert('120.0340.678-8');` - [PolishIdCard][] - `v::polishIdCard()->assert('AYW036733');` - [PortugueseNif][] - `v::portugueseNif()->assert('124885446');` - [Positive][] - `v::positive()->assert(1);` - [PostalCode][] - `v::postalCode('BR')->assert('02179000');` -- [PrimeNumber][] - `v::primeNumber()->assert(7);` - [Printable][] - `v::printable()->assert('LMKA0$% _123');` - [Property][] - `v::property('name', v::equals('The Respect Panda'))->assert($object);` - [PropertyExists][] - `v::propertyExists('name')->assert($object);` @@ -206,12 +201,10 @@ In this page you will find a list of validators by their category. - [Undef][] - `v::undef()->assert('');` - [UndefOr][] - `v::undefOr(v::alpha())->assert('');` - [Unique][] - `v::unique()->assert([]);` -- [Uploaded][] - `` - [Uppercase][] - `v::uppercase()->assert('W3C');` - [Url][] - `v::url()->assert('http://example.com');` - [Uuid][] - `v::uuid()->assert('eb3115e5-bd16-4939-ab12-2b95745a30f3');` - [Version][] - `v::version()->assert('1.0.0');` -- [VideoUrl][] - `v::videoUrl()->assert('https://player.vimeo.com/video/71787467');` - [Vowel][] - `v::vowel()->assert('aei');` - [When][] - `v::when(v::intVal(), v::positive(), v::notBlank())->assert(1);` - [Writable][] - `v::writable()->assert('/path/to/file');` @@ -272,9 +265,7 @@ In this page you will find a list of validators by their category. [Factor]: validators/Factor.md "Validates if the input is a factor of the defined dividend." [FalseVal]: validators/FalseVal.md "Validates if a value is considered as `false`." [Falsy]: validators/Falsy.md "Validates whether the given input is considered empty or falsy, similar to PHP's `empty()` function." -[Fibonacci]: validators/Fibonacci.md "Validates whether the input follows the Fibonacci integer sequence." [File]: validators/File.md "Validates whether file input is as a regular filename." -[FilterVar]: validators/FilterVar.md "Validates the input with the PHP's filter_var() function." [Finite]: validators/Finite.md "Validates if the input is a finite number." [FloatType]: validators/FloatType.md "Validates whether the type of the input is float." [FloatVal]: validators/FloatVal.md "Validate whether the input value is float." @@ -329,16 +320,13 @@ In this page you will find a list of validators by their category. [ObjectType]: validators/ObjectType.md "Validates whether the input is an object." [Odd]: validators/Odd.md "Validates whether the input is an odd number or not." [OneOf]: validators/OneOf.md "Will validate if exactly one inner validator passes." -[PerfectSquare]: validators/PerfectSquare.md "Validates whether the input is a perfect square." [Pesel]: validators/Pesel.md "Validates PESEL (Polish human identification number)." [Phone]: validators/Phone.md "Validates whether the input is a valid phone number. This validator requires" -[PhpLabel]: validators/PhpLabel.md "Validates if a value is considered a valid PHP Label," [Pis]: validators/Pis.md "Validates a Brazilian PIS/NIS number ignoring any non-digit char." [PolishIdCard]: validators/PolishIdCard.md "Validates whether the input is a Polish identity card (Dowód Osobisty)." [PortugueseNif]: validators/PortugueseNif.md "Validates Portugal's fiscal identification number (NIF)." [Positive]: validators/Positive.md "Validates whether the input is a positive number." [PostalCode]: validators/PostalCode.md "Validates whether the input is a valid postal code or not." -[PrimeNumber]: validators/PrimeNumber.md "Validates a prime number" [Printable]: validators/Printable.md "Similar to `Graph` but accepts whitespace." [Property]: validators/Property.md "Validates an object property against a given validator." [PropertyExists]: validators/PropertyExists.md "Validates if an object property exists." @@ -368,12 +356,10 @@ In this page you will find a list of validators by their category. [Undef]: validators/Undef.md "Validates if the given input is undefined. By _undefined_ we consider `null` or an empty string (`''`)." [UndefOr]: validators/UndefOr.md "Validates the input using a defined validator when the input is not `null` or an empty string (`''`)." [Unique]: validators/Unique.md "Validates whether the input array contains only unique values." -[Uploaded]: validators/Uploaded.md "Validates if the given data is a file that was uploaded via HTTP POST." [Uppercase]: validators/Uppercase.md "Validates whether the characters in the input are uppercase." [Url]: validators/Url.md "Validates whether the input is a URL." [Uuid]: validators/Uuid.md "Validates whether the input is a valid UUID. It also supports validation of" [Version]: validators/Version.md "Validates version numbers using Semantic Versioning." -[VideoUrl]: validators/VideoUrl.md "Validates if the input is a video URL value." [Vowel]: validators/Vowel.md "Validates whether the input contains only vowels." [When]: validators/When.md "A ternary validator that accepts three parameters." [Writable]: validators/Writable.md "Validates if the given input is writable file." diff --git a/docs/validators/Fibonacci.md b/docs/validators/Fibonacci.md deleted file mode 100644 index 2e941cd71..000000000 --- a/docs/validators/Fibonacci.md +++ /dev/null @@ -1,52 +0,0 @@ - - -# Fibonacci - -- `Fibonacci()` - -Validates whether the input follows the Fibonacci integer sequence. - -```php -v::fibonacci()->assert(1); -// Validation passes successfully - -v::fibonacci()->assert('34'); -// Validation passes successfully - -v::fibonacci()->assert(6); -// → 6 must be a valid Fibonacci number -``` - -## Templates - -### `Fibonacci::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :----------------------------------------------- | -| `default` | {{subject}} must be a valid Fibonacci number | -| `inverted` | {{subject}} must not be a valid Fibonacci number | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- Math -- Numbers - -## Changelog - -| Version | Description | -| ------: | :---------- | -| 1.1.0 | Created | - -## See Also - -- [PerfectSquare](PerfectSquare.md) -- [PrimeNumber](PrimeNumber.md) diff --git a/docs/validators/FilterVar.md b/docs/validators/FilterVar.md deleted file mode 100644 index 56bb55083..000000000 --- a/docs/validators/FilterVar.md +++ /dev/null @@ -1,64 +0,0 @@ - - -# FilterVar - -- `FilterVar(int $filter)` -- `FilterVar(int $filter, mixed $options)` - -Validates the input with the PHP's [filter_var()](http://php.net/filter_var) function. - -```php -v::filterVar(FILTER_VALIDATE_EMAIL)->assert('bob@example.com'); -// Validation passes successfully - -v::filterVar(FILTER_VALIDATE_URL)->assert('http://example.com'); -// Validation passes successfully - -v::filterVar(FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)->assert('http://example.com'); -// → "http://example.com" must be valid - -v::filterVar(FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED)->assert('http://example.com/path'); -// Validation passes successfully - -v::filterVar(FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)->assert('webserver.local'); -// Validation passes successfully - -v::filterVar(FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)->assert('@local'); -// → "@local" must be valid -``` - -## Templates - -### `FilterVar::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :---------------------------- | -| `default` | {{subject}} must be valid | -| `inverted` | {{subject}} must not be valid | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- Miscellaneous - -## Changelog - -| Version | Description | -| ------: | :----------------------------------------------------------------- | -| 2.3.0 | `v::filterVar(FILTER_VALIDATE_INT)->isValid(0)` is no longer false | -| 2.0.15 | Allow validating domains | -| 0.8.0 | Created | - -## See Also - -- [Callback](Callback.md) -- [Json](Json.md) -- [Url](Url.md) diff --git a/docs/validators/PerfectSquare.md b/docs/validators/PerfectSquare.md deleted file mode 100644 index 6ebbfbcbf..000000000 --- a/docs/validators/PerfectSquare.md +++ /dev/null @@ -1,50 +0,0 @@ - - -# PerfectSquare - -- `PerfectSquare()` - -Validates whether the input is a perfect square. - -```php -v::perfectSquare()->assert(25); // (5*5) -// Validation passes successfully - -v::perfectSquare()->assert(9); // (3*3) -// Validation passes successfully -``` - -## Templates - -### `PerfectSquare::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :---------------------------------------------- | -| `default` | {{subject}} must be a perfect square number | -| `inverted` | {{subject}} must not be a perfect square number | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- Math -- Numbers - -## Changelog - -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | - -## See Also - -- [Factor](Factor.md) -- [Fibonacci](Fibonacci.md) -- [PrimeNumber](PrimeNumber.md) diff --git a/docs/validators/PhpLabel.md b/docs/validators/PhpLabel.md deleted file mode 100644 index 78bcab4c4..000000000 --- a/docs/validators/PhpLabel.md +++ /dev/null @@ -1,57 +0,0 @@ - - -# PhpLabel - -- `PhpLabel()` - -Validates if a value is considered a valid PHP Label, -so that it can be used as a _variable_, _function_ or _class_ name, for example. - -Reference: -http://php.net/manual/en/language.variables.basics.php - -```php -v::phpLabel()->assert('person'); //true -// Validation passes successfully - -v::phpLabel()->assert('foo'); //true -// Validation passes successfully - -v::phpLabel()->assert('4ccess'); //false -// → "4ccess" must be a valid PHP label -``` - -## Templates - -### `PhpLabel::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :---------------------------------------- | -| `default` | {{subject}} must be a valid PHP label | -| `inverted` | {{subject}} must not be a valid PHP label | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- Strings - -## Changelog - -| Version | Description | -| ------: | :---------- | -| 1.1.0 | Created | - -## See Also - -- [Charset](Charset.md) -- [Regex](Regex.md) -- [ResourceType](ResourceType.md) -- [Slug](Slug.md) diff --git a/docs/validators/PrimeNumber.md b/docs/validators/PrimeNumber.md deleted file mode 100644 index 59f0728a1..000000000 --- a/docs/validators/PrimeNumber.md +++ /dev/null @@ -1,48 +0,0 @@ - - -# PrimeNumber - -- `PrimeNumber()` - -Validates a prime number - -```php -v::primeNumber()->assert(7); -// Validation passes successfully -``` - -## Templates - -### `PrimeNumber::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :------------------------------------- | -| `default` | {{subject}} must be a prime number | -| `inverted` | {{subject}} must not be a prime number | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- Math -- Numbers - -## Changelog - -| Version | Description | -| ------: | :---------- | -| 0.3.9 | Created | - -## See Also - -- [Factor](Factor.md) -- [Fibonacci](Fibonacci.md) -- [Multiple](Multiple.md) -- [PerfectSquare](PerfectSquare.md) diff --git a/docs/validators/Uploaded.md b/docs/validators/Uploaded.md deleted file mode 100644 index 34c29689a..000000000 --- a/docs/validators/Uploaded.md +++ /dev/null @@ -1,50 +0,0 @@ - - -# Uploaded - -- `Uploaded()` - -Validates if the given data is a file that was uploaded via HTTP POST. - -## Templates - -### `Uploaded::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :--------------------------------------- | -| `default` | {{subject}} must be an uploaded file | -| `inverted` | {{subject}} must not be an uploaded file | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- File system - -## Changelog - -| Version | Description | -| ------: | :---------------- | -| 2.1.0 | Add PSR-7 support | -| 0.5.0 | Created | - -## See Also - -- [Directory](Directory.md) -- [Executable](Executable.md) -- [Exists](Exists.md) -- [Extension](Extension.md) -- [File](File.md) -- [Image](Image.md) -- [Mimetype](Mimetype.md) -- [Readable](Readable.md) -- [Size](Size.md) -- [SymbolicLink](SymbolicLink.md) -- [Writable](Writable.md) diff --git a/docs/validators/VideoUrl.md b/docs/validators/VideoUrl.md deleted file mode 100644 index 4191b865d..000000000 --- a/docs/validators/VideoUrl.md +++ /dev/null @@ -1,109 +0,0 @@ - - -# VideoUrl - -- `VideoUrl()` -- `VideoUrl(string $service)` - -Validates if the input is a video URL value. - -```php -v::videoUrl()->assert('https://player.vimeo.com/video/71787467'); -// Validation passes successfully - -v::videoUrl()->assert('https://vimeo.com/71787467'); -// Validation passes successfully - -v::videoUrl()->assert('https://www.youtube.com/embed/netHLn9TScY'); -// Validation passes successfully - -v::videoUrl()->assert('https://www.youtube.com/watch?v=netHLn9TScY'); -// Validation passes successfully - -v::videoUrl()->assert('https://youtu.be/netHLn9TScY'); -// Validation passes successfully - -v::videoUrl()->assert('https://www.twitch.tv/videos/320689092'); -// Validation passes successfully - -v::videoUrl()->assert('https://clips.twitch.tv/BitterLazyMangetoutHumbleLife'); -// Validation passes successfully - -v::videoUrl('youtube')->assert('https://www.youtube.com/watch?v=netHLn9TScY'); -// Validation passes successfully - -v::videoUrl('vimeo')->assert('https://vimeo.com/71787467'); -// Validation passes successfully - -v::videoUrl('twitch')->assert('https://www.twitch.tv/videos/320689092'); -// Validation passes successfully - -v::videoUrl('twitch')->assert('https://clips.twitch.tv/BitterLazyMangetoutHumbleLife'); -// Validation passes successfully - -v::videoUrl()->assert('https://youtube.com'); -// → "https://youtube.com" must be a valid video URL - -v::videoUrl('youtube')->assert('https://vimeo.com/71787467'); -// → "https://vimeo.com/71787467" must be a valid youtube video URL - -v::videoUrl('twitch')->assert('https://clips.twitch.tv/videos/90210'); -// → "https://clips.twitch.tv/videos/90210" must be a valid twitch video URL - -v::videoUrl('twitch')->assert('https://twitch.tv/TakeTeaAndNoTea'); -// → "https://twitch.tv/TakeTeaAndNoTea" must be a valid twitch video URL -``` - -The services accepted are: - -- YouTube -- Vimeo -- Twitch (videos and clips) - -The `$service` value is not case-sensitive. - -Message template for this validator includes `{{service}}`. - -## Templates - -### `VideoUrl::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------: | :---------------------------------------- | -| `default` | {{subject}} must be a valid video URL | -| `inverted` | {{subject}} must not be a valid video URL | - -### `VideoUrl::TEMPLATE_SERVICE` - -| Mode | Template | -| ---------: | :------------------------------------------------------------- | -| `default` | {{subject}} must be a valid {{service|raw}} video URL | -| `inverted` | {{subject}} must not be a valid {{service|raw}} video URL | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | -| `service` | | - -## Categorization - -- Internet - -## Changelog - -| Version | Description | -| ------: | :---------- | -| 1.0.0 | Created | - -## See Also - -- [Email](Email.md) -- [Json](Json.md) -- [Phone](Phone.md) -- [Slug](Slug.md) -- [Url](Url.md) diff --git a/phpbench.json.dist b/phpbench.json.dist index 02b5ce3b7..761d7065f 100644 --- a/phpbench.json.dist +++ b/phpbench.json.dist @@ -1,6 +1,6 @@ { "$schema": "./vendor/phpbench/phpbench/phpbench.schema.json", - "runner.bootstrap": "tests/bootstrap.php", + "runner.bootstrap": "vendor/autoload.php", "runner.path": "tests/benchmark", "runner.file_pattern": "*Bench.php" } \ No newline at end of file diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 978589ab9..20d17139b 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -18,7 +18,6 @@ - tests/bootstrap.php src/Validators/Tld.php @@ -37,5 +36,4 @@ tests/Pest.php tests/feature - tests/bootstrap.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5ab451889..51339be5c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Samuel Heinzmann - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Respect\Validation\Message\Template; -use Respect\Validation\Validators\Core\Simple; - -use function is_numeric; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be a valid Fibonacci number', - '{{subject}} must not be a valid Fibonacci number', -)] -final class Fibonacci extends Simple -{ - public function isValid(mixed $input): bool - { - if (!is_numeric($input)) { - return false; - } - - $sequence = [0, 1]; - $position = 1; - while ($input > $sequence[$position]) { - ++$position; - $sequence[$position] = $sequence[$position - 1] + $sequence[$position - 2]; - } - - return $sequence[$position] === (int) $input; - } -} diff --git a/src/Validators/FilterVar.php b/src/Validators/FilterVar.php deleted file mode 100644 index 244233fc1..000000000 --- a/src/Validators/FilterVar.php +++ /dev/null @@ -1,69 +0,0 @@ - - * SPDX-FileContributor: Chris Ramakers - * SPDX-FileContributor: Henrique Moody - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Respect\Validation\Exceptions\InvalidValidatorException; -use Respect\Validation\Message\Template; -use Respect\Validation\Result; -use Respect\Validation\Validator; - -use function array_key_exists; -use function filter_var; - -use const FILTER_VALIDATE_BOOLEAN; -use const FILTER_VALIDATE_DOMAIN; -use const FILTER_VALIDATE_EMAIL; -use const FILTER_VALIDATE_FLOAT; -use const FILTER_VALIDATE_INT; -use const FILTER_VALIDATE_IP; -use const FILTER_VALIDATE_REGEXP; -use const FILTER_VALIDATE_URL; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be valid', - '{{subject}} must not be valid', -)] -final readonly class FilterVar implements Validator -{ - private const array ALLOWED_FILTERS = [ - FILTER_VALIDATE_BOOLEAN => 'is_bool', - FILTER_VALIDATE_DOMAIN => 'is_string', - FILTER_VALIDATE_EMAIL => 'is_string', - FILTER_VALIDATE_FLOAT => 'is_float', - FILTER_VALIDATE_INT => 'is_int', - FILTER_VALIDATE_IP => 'is_string', - FILTER_VALIDATE_REGEXP => 'is_string', - FILTER_VALIDATE_URL => 'is_string', - ]; - - public function __construct(private int $filter, private mixed $options = null) - { - if (!array_key_exists($filter, self::ALLOWED_FILTERS)) { - throw new InvalidValidatorException('Cannot accept the given filter'); - } - } - - public function evaluate(mixed $input): Result - { - return Result::of( - (self::ALLOWED_FILTERS[$this->filter])(match ($this->options) { - null => filter_var($input, $this->filter), - default => filter_var($input, $this->filter, $this->options), - }), - $input, - $this, - ); - } -} diff --git a/src/Validators/PerfectSquare.php b/src/Validators/PerfectSquare.php deleted file mode 100644 index a26d80391..000000000 --- a/src/Validators/PerfectSquare.php +++ /dev/null @@ -1,38 +0,0 @@ - - * SPDX-FileContributor: Danilo Benevides - * SPDX-FileContributor: Felipe Martins - * SPDX-FileContributor: Graham Campbell - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Kleber Hamada Sato - * SPDX-FileContributor: Nick Lombard - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Respect\Validation\Message\Template; -use Respect\Validation\Validators\Core\Simple; - -use function floor; -use function is_numeric; -use function sqrt; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be a perfect square number', - '{{subject}} must not be a perfect square number', -)] -final class PerfectSquare extends Simple -{ - public function isValid(mixed $input): bool - { - return is_numeric($input) && floor(sqrt((float) $input)) == sqrt((float) $input); - } -} diff --git a/src/Validators/PhpLabel.php b/src/Validators/PhpLabel.php deleted file mode 100644 index d58bd34c2..000000000 --- a/src/Validators/PhpLabel.php +++ /dev/null @@ -1,38 +0,0 @@ - - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Emmerson - * SPDX-FileContributor: Graham Campbell - * SPDX-FileContributor: Guilherme Siani - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: João Torquato - * SPDX-FileContributor: Nick Lombard - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Respect\Validation\Message\Template; -use Respect\Validation\Validators\Core\Simple; - -use function is_string; -use function preg_match; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be a valid PHP label', - '{{subject}} must not be a valid PHP label', -)] -final class PhpLabel extends Simple -{ - public function isValid(mixed $input): bool - { - return is_string($input) && preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $input); - } -} diff --git a/src/Validators/PrimeNumber.php b/src/Validators/PrimeNumber.php deleted file mode 100644 index a35ee8325..000000000 --- a/src/Validators/PrimeNumber.php +++ /dev/null @@ -1,54 +0,0 @@ - - * SPDX-FileContributor: Alexandre Gomes Gaigalas - * SPDX-FileContributor: Camilo Teixeira de Melo - * SPDX-FileContributor: Graham Campbell - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Ismael Elias - * SPDX-FileContributor: Kleber Hamada Sato - * SPDX-FileContributor: kmilotxm@gmail.com - * SPDX-FileContributor: Nick Lombard - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Respect\Validation\Message\Template; -use Respect\Validation\Validators\Core\Simple; - -use function ceil; -use function is_numeric; -use function sqrt; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be a prime number', - '{{subject}} must not be a prime number', -)] -final class PrimeNumber extends Simple -{ - public function isValid(mixed $input): bool - { - if (!is_numeric($input) || $input <= 1) { - return false; - } - - if ($input != 2 && ($input % 2) == 0) { - return false; - } - - for ($i = 3; $i <= ceil(sqrt((float) $input)); $i += 2) { - if ($input % $i == 0) { - return false; - } - } - - return true; - } -} diff --git a/src/Validators/Uploaded.php b/src/Validators/Uploaded.php deleted file mode 100644 index 3730bed8a..000000000 --- a/src/Validators/Uploaded.php +++ /dev/null @@ -1,55 +0,0 @@ - - * SPDX-FileContributor: Graham Campbell - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Nick Lombard - * SPDX-FileContributor: paul karikari - * SPDX-FileContributor: v0idpwn - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Psr\Http\Message\UploadedFileInterface; -use Respect\Validation\Message\Template; -use Respect\Validation\Validators\Core\Simple; -use SplFileInfo; - -use function function_exists; -use function is_scalar; -use function is_uploaded_file; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be an uploaded file', - '{{subject}} must not be an uploaded file', -)] -final class Uploaded extends Simple -{ - public function isValid(mixed $input): bool - { - if ($input instanceof SplFileInfo) { - return $this->isValid($input->getPathname()); - } - - if ($input instanceof UploadedFileInterface) { - return true; - } - - if (!is_scalar($input)) { - return false; - } - - if (function_exists('mock_is_uploaded_file')) { - return mock_is_uploaded_file((string) $input); - } - - return is_uploaded_file((string) $input); - } -} diff --git a/src/Validators/Url.php b/src/Validators/Url.php index 1f91ed70b..9d2941f36 100644 --- a/src/Validators/Url.php +++ b/src/Validators/Url.php @@ -13,7 +13,9 @@ use Attribute; use Respect\Validation\Message\Template; -use Respect\Validation\Validators\Core\Envelope; +use Respect\Validation\Validators\Core\Simple; + +use function filter_var; use const FILTER_VALIDATE_URL; @@ -22,10 +24,10 @@ '{{subject}} must be a URL', '{{subject}} must not be a URL', )] -final class Url extends Envelope +final class Url extends Simple { - public function __construct() + public function isValid(mixed $input): bool { - parent::__construct(new FilterVar(FILTER_VALIDATE_URL)); + return filter_var($input, FILTER_VALIDATE_URL) !== false; } } diff --git a/src/Validators/VideoUrl.php b/src/Validators/VideoUrl.php deleted file mode 100644 index 9e12ee95f..000000000 --- a/src/Validators/VideoUrl.php +++ /dev/null @@ -1,91 +0,0 @@ - - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Emmerson Siqueira - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Ricardo Gobbo - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use Attribute; -use Respect\Validation\Exceptions\InvalidValidatorException; -use Respect\Validation\Message\Template; -use Respect\Validation\Result; -use Respect\Validation\Validator; - -use function array_keys; -use function is_string; -use function mb_strtolower; -use function preg_match; - -#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] -#[Template( - '{{subject}} must be a valid video URL', - '{{subject}} must not be a valid video URL', - self::TEMPLATE_STANDARD, -)] -#[Template( - '{{subject}} must be a valid {{service|raw}} video URL', - '{{subject}} must not be a valid {{service|raw}} video URL', - self::TEMPLATE_SERVICE, -)] -final class VideoUrl implements Validator -{ - public const string TEMPLATE_SERVICE = '__service__'; - - private const array SERVICES = [ - // phpcs:disable Generic.Files.LineLength.TooLong - 'youtube' => '@^https?://(www\.)?(?:youtube\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^\"&?/]{11})@i', - 'vimeo' => '@^https?://(www\.)?(player\.)?(vimeo\.com/)((channels/[A-z]+/)|(groups/[A-z]+/videos/)|(video/))?([0-9]+)@i', - 'twitch' => '@^https?://(((www\.)?twitch\.tv/videos/[0-9]+)|clips\.twitch\.tv/[a-zA-Z]+)$@i', - // phpcs:enable Generic.Files.LineLength.TooLong - ]; - - public function __construct( - private readonly string|null $service = null, - ) { - if ($service !== null && !$this->isSupportedService($service)) { - throw new InvalidValidatorException('"%s" is not a recognized video service.', $service); - } - } - - public function evaluate(mixed $input): Result - { - $parameters = ['service' => $this->service]; - $template = $this->service !== null ? self::TEMPLATE_SERVICE : self::TEMPLATE_STANDARD; - if (!is_string($input)) { - return Result::failed($input, $this, $parameters, $template); - } - - if ($this->service !== null) { - return Result::of($this->isValid($this->service, $input), $input, $this, $parameters, $template); - } - - foreach (array_keys(self::SERVICES) as $service) { - if (!$this->isValid($service, $input)) { - continue; - } - - return Result::passed($input, $this, $parameters, $template); - } - - return Result::failed($input, $this, $parameters, $template); - } - - private function isSupportedService(string $service): bool - { - return isset(self::SERVICES[mb_strtolower($service)]); - } - - private function isValid(string $service, string $input): bool - { - return preg_match(self::SERVICES[mb_strtolower($service)], $input) > 0; - } -} diff --git a/tests/benchmark/ValidatorBench.php b/tests/benchmark/ValidatorBench.php index 03781dd74..bf34a5777 100644 --- a/tests/benchmark/ValidatorBench.php +++ b/tests/benchmark/ValidatorBench.php @@ -20,7 +20,6 @@ class ValidatorBench /** @param array $params */ #[Bench\ParamProviders(['provideValidatorInput'])] - #[Bench\BeforeMethods('setFileUploadMock')] #[Bench\Iterations(10)] #[Bench\RetryThreshold(5)] #[Bench\Revs(5)] @@ -36,9 +35,4 @@ public function evaluate(array $params): void [$v, $input] = $params; $v->evaluate($input); } - - public function setFileUploadMock(): void - { - set_mock_is_uploaded_file_return(true); - } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index fbc19b35d..7579f8ac4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -11,19 +11,3 @@ declare(strict_types=1); require __DIR__ . '/../vendor/autoload.php'; - -$mockIsUploadedFileReturn = true; - -function mock_is_uploaded_file(string $filename): bool -{ - global $mockIsUploadedFileReturn; - - return $mockIsUploadedFileReturn; -} - -function set_mock_is_uploaded_file_return(bool $return): void -{ - global $mockIsUploadedFileReturn; - - $mockIsUploadedFileReturn = $return; -} diff --git a/tests/feature/SerializableTest.php b/tests/feature/SerializableTest.php index 7fdc90813..93ba3cfd3 100644 --- a/tests/feature/SerializableTest.php +++ b/tests/feature/SerializableTest.php @@ -11,7 +11,6 @@ use Respect\Validation\Test\SmokeTestProvider; test('Can be serialized and unserialized', function ($validator, $input): void { - set_mock_is_uploaded_file_return(true); expect( unserialize(serialize($validator))->evaluate($input)->hasPassed, )->toBeTrue(); diff --git a/tests/feature/Validators/DateTimeDiffTest.php b/tests/feature/Validators/DateTimeDiffTest.php index ea913b1f0..a4912cad5 100644 --- a/tests/feature/Validators/DateTimeDiffTest.php +++ b/tests/feature/Validators/DateTimeDiffTest.php @@ -126,38 +126,38 @@ )); test('Without adjacent result', catchAll( - fn() => v::dateTimeDiff('years', v::primeNumber()->between(2, 5))->assert('1 year ago'), + fn() => v::dateTimeDiff('years', v::positive()->between(2, 5))->assert('1 year ago'), fn(string $message, string $fullMessage, array $messages) => expect() - ->and($message)->toBe('The number of years between now and "1 year ago" must be a prime number') + ->and($message)->toBe('The number of years between now and "1 year ago" must be a positive number') ->and($fullMessage)->toBe(<<<'FULL_MESSAGE' - "1 year ago" must pass all the rules - - The number of years between now and "1 year ago" must be a prime number + - The number of years between now and "1 year ago" must be a positive number - The number of years between now and "1 year ago" must be between 2 and 5 FULL_MESSAGE) ->and($messages)->toBe([ '__root__' => '"1 year ago" must pass all the rules', - 'dateTimeDiffPrimeNumber' => 'The number of years between now and "1 year ago" must be a prime number', + 'dateTimeDiffPositive' => 'The number of years between now and "1 year ago" must be a positive number', 'dateTimeDiffBetween' => 'The number of years between now and "1 year ago" must be between 2 and 5', ]), )); test('Without adjacent result with templates', catchAll( - fn() => v::dateTimeDiff('years', v::primeNumber()->between(2, 5))->assert('1 year ago', [ + fn() => v::dateTimeDiff('years', v::positive()->between(2, 5))->assert('1 year ago', [ 'dateTimeDiff' => [ - 'primeNumber' => 'Interval must be a valid prime number', + 'positive' => 'Interval must be a positive number', 'between' => 'Interval must be between 2 and 5', ], ]), fn(string $message, string $fullMessage, array $messages) => expect() - ->and($message)->toBe('The number of years between now and "1 year ago" must be a prime number') + ->and($message)->toBe('The number of years between now and "1 year ago" must be a positive number') ->and($fullMessage)->toBe(<<<'FULL_MESSAGE' - "1 year ago" must pass all the rules - - The number of years between now and "1 year ago" must be a prime number + - The number of years between now and "1 year ago" must be a positive number - The number of years between now and "1 year ago" must be between 2 and 5 FULL_MESSAGE) ->and($messages)->toBe([ '__root__' => '"1 year ago" must pass all the rules', - 'dateTimeDiffPrimeNumber' => 'The number of years between now and "1 year ago" must be a prime number', + 'dateTimeDiffPositive' => 'The number of years between now and "1 year ago" must be a positive number', 'dateTimeDiffBetween' => 'The number of years between now and "1 year ago" must be between 2 and 5', ]), )); diff --git a/tests/feature/Validators/FibonacciTest.php b/tests/feature/Validators/FibonacciTest.php deleted file mode 100644 index 295349e31..000000000 --- a/tests/feature/Validators/FibonacciTest.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::fibonacci()->assert(4), - fn(string $message) => expect($message)->toBe('4 must be a valid Fibonacci number'), -)); - -test('Scenario #2', catchMessage( - fn() => v::not(v::fibonacci())->assert(5), - fn(string $message) => expect($message)->toBe('5 must not be a valid Fibonacci number'), -)); - -test('Scenario #3', catchFullMessage( - fn() => v::fibonacci()->assert(16), - fn(string $fullMessage) => expect($fullMessage)->toBe('- 16 must be a valid Fibonacci number'), -)); - -test('Scenario #4', catchFullMessage( - fn() => v::not(v::fibonacci())->assert(21), - fn(string $fullMessage) => expect($fullMessage)->toBe('- 21 must not be a valid Fibonacci number'), -)); diff --git a/tests/feature/Validators/FilterVarTest.php b/tests/feature/Validators/FilterVarTest.php deleted file mode 100644 index 3442ed4cf..000000000 --- a/tests/feature/Validators/FilterVarTest.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::filterVar(FILTER_VALIDATE_IP)->assert(42), - fn(string $message) => expect($message)->toBe('42 must be valid'), -)); - -test('Scenario #2', catchMessage( - fn() => v::not(v::filterVar(FILTER_VALIDATE_BOOLEAN))->assert('On'), - fn(string $message) => expect($message)->toBe('"On" must not be valid'), -)); - -test('Scenario #3', catchFullMessage( - fn() => v::filterVar(FILTER_VALIDATE_EMAIL)->assert(1.5), - fn(string $fullMessage) => expect($fullMessage)->toBe('- 1.5 must be valid'), -)); - -test('Scenario #4', catchFullMessage( - fn() => v::not(v::filterVar(FILTER_VALIDATE_FLOAT))->assert(1.0), - fn(string $fullMessage) => expect($fullMessage)->toBe('- 1.0 must not be valid'), -)); diff --git a/tests/feature/Validators/PerfectSquareTest.php b/tests/feature/Validators/PerfectSquareTest.php deleted file mode 100644 index 9805b3e23..000000000 --- a/tests/feature/Validators/PerfectSquareTest.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::perfectSquare()->assert(250), - fn(string $message) => expect($message)->toBe('250 must be a perfect square number'), -)); - -test('Scenario #2', catchMessage( - fn() => v::not(v::perfectSquare())->assert(9), - fn(string $message) => expect($message)->toBe('9 must not be a perfect square number'), -)); - -test('Scenario #3', catchFullMessage( - fn() => v::perfectSquare()->assert(7), - fn(string $fullMessage) => expect($fullMessage)->toBe('- 7 must be a perfect square number'), -)); - -test('Scenario #4', catchFullMessage( - fn() => v::not(v::perfectSquare())->assert(400), - fn(string $fullMessage) => expect($fullMessage)->toBe('- 400 must not be a perfect square number'), -)); diff --git a/tests/feature/Validators/PhplabelTest.php b/tests/feature/Validators/PhplabelTest.php deleted file mode 100644 index 35b58217a..000000000 --- a/tests/feature/Validators/PhplabelTest.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::phpLabel()->assert('f o o'), - fn(string $message) => expect($message)->toBe('"f o o" must be a valid PHP label'), -)); - -test('Scenario #2', catchMessage( - fn() => v::not(v::phpLabel())->assert('correctOne'), - fn(string $message) => expect($message)->toBe('"correctOne" must not be a valid PHP label'), -)); - -test('Scenario #3', catchFullMessage( - fn() => v::phpLabel()->assert('0wner'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "0wner" must be a valid PHP label'), -)); - -test('Scenario #4', catchFullMessage( - fn() => v::not(v::phpLabel())->assert('Respect'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "Respect" must not be a valid PHP label'), -)); diff --git a/tests/feature/Validators/PrimeNumberTest.php b/tests/feature/Validators/PrimeNumberTest.php deleted file mode 100644 index c978f28db..000000000 --- a/tests/feature/Validators/PrimeNumberTest.php +++ /dev/null @@ -1,29 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::primeNumber()->assert(10), - fn(string $message) => expect($message)->toBe('10 must be a prime number'), -)); - -test('Scenario #2', catchMessage( - fn() => v::not(v::primeNumber())->assert(3), - fn(string $message) => expect($message)->toBe('3 must not be a prime number'), -)); - -test('Scenario #3', catchFullMessage( - fn() => v::primeNumber()->assert('Foo'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "Foo" must be a prime number'), -)); - -test('Scenario #4', catchFullMessage( - fn() => v::not(v::primeNumber())->assert('+7'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "+7" must not be a prime number'), -)); diff --git a/tests/feature/Validators/UploadedTest.php b/tests/feature/Validators/UploadedTest.php deleted file mode 100644 index 825578079..000000000 --- a/tests/feature/Validators/UploadedTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - function (): void { - set_mock_is_uploaded_file_return(false); - v::uploaded()->assert('filename'); - }, - fn(string $message) => expect($message)->toBe('"filename" must be an uploaded file'), -)); - -test('Scenario #2', catchMessage( - function (): void { - set_mock_is_uploaded_file_return(true); - v::not(v::uploaded())->assert('filename'); - }, - fn(string $message) => expect($message)->toBe('"filename" must not be an uploaded file'), -)); - -test('Scenario #3', catchFullMessage( - function (): void { - set_mock_is_uploaded_file_return(false); - v::uploaded()->assert('filename'); - }, - fn(string $fullMessage) => expect($fullMessage)->toBe('- "filename" must be an uploaded file'), -)); - -test('Scenario #4', catchFullMessage( - function (): void { - set_mock_is_uploaded_file_return(true); - v::not(v::uploaded())->assert('filename'); - }, - fn(string $fullMessage) => expect($fullMessage)->toBe('- "filename" must not be an uploaded file'), -)); diff --git a/tests/feature/Validators/VideoUrlTest.php b/tests/feature/Validators/VideoUrlTest.php deleted file mode 100644 index e128a90c1..000000000 --- a/tests/feature/Validators/VideoUrlTest.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::videoUrl()->assert('example.com'), - fn(string $message) => expect($message)->toBe('"example.com" must be a valid video URL'), -)); - -test('Scenario #2', catchMessage( - fn() => v::videoUrl('YouTube')->assert('example.com'), - fn(string $message) => expect($message)->toBe('"example.com" must be a valid YouTube video URL'), -)); - -test('Scenario #3', catchMessage( - fn() => v::not(v::videoUrl())->assert('https://player.vimeo.com/video/7178746722'), - fn(string $message) => expect($message)->toBe('"https://player.vimeo.com/video/7178746722" must not be a valid video URL'), -)); - -test('Scenario #4', catchMessage( - fn() => v::not(v::videoUrl('YouTube'))->assert('https://www.youtube.com/embed/netHLn9TScY'), - fn(string $message) => expect($message)->toBe('"https://www.youtube.com/embed/netHLn9TScY" must not be a valid YouTube video URL'), -)); - -test('Scenario #5', catchFullMessage( - fn() => v::videoUrl()->assert('example.com'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "example.com" must be a valid video URL'), -)); - -test('Scenario #6', catchFullMessage( - fn() => v::videoUrl('Vimeo')->assert('example.com'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "example.com" must be a valid Vimeo video URL'), -)); - -test('Scenario #7', catchFullMessage( - fn() => v::not(v::videoUrl())->assert('https://youtu.be/netHLn9TScY'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "https://youtu.be/netHLn9TScY" must not be a valid video URL'), -)); - -test('Scenario #8', catchFullMessage( - fn() => v::not(v::videoUrl('Vimeo'))->assert('https://vimeo.com/71787467'), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "https://vimeo.com/71787467" must not be a valid Vimeo video URL'), -)); diff --git a/tests/src/SmokeTestProvider.php b/tests/src/SmokeTestProvider.php index b7ea5b2f4..6bd45d34a 100644 --- a/tests/src/SmokeTestProvider.php +++ b/tests/src/SmokeTestProvider.php @@ -17,7 +17,6 @@ use function fopen; -use const FILTER_VALIDATE_EMAIL; use const INF; trait SmokeTestProvider @@ -79,9 +78,7 @@ public static function provideValidatorInput(): Generator yield 'Factor' => [new vs\Factor(0), 36]; yield 'FalseVal' => [new vs\FalseVal(), false]; yield 'Falsy' => [new vs\Falsy(), 0]; - yield 'Fibonacci' => [new vs\Fibonacci(), 13]; yield 'File' => [new vs\File(), __FILE__]; - yield 'FilterVar' => [new vs\FilterVar(FILTER_VALIDATE_EMAIL), 'bob@example.com']; yield 'Finite' => [new vs\Finite(), 1.23]; yield 'FloatType' => [new vs\FloatType(), 1.23]; yield 'FloatVal' => [new vs\FloatVal(), 1.23]; @@ -136,16 +133,13 @@ public static function provideValidatorInput(): Generator yield 'ObjectType' => [new vs\ObjectType(), new stdClass()]; yield 'Odd' => [new vs\Odd(), 3]; yield 'OneOf' => [new vs\OneOf(new vs\Digit(), new vs\Alpha()), 'AB']; - yield 'PerfectSquare' => [new vs\PerfectSquare(), 16]; yield 'Pesel' => [new vs\Pesel(), '21120209256']; yield 'Phone' => [new vs\Phone(), '+1 650 253 00 00']; - yield 'PhpLabel' => [new vs\PhpLabel(), 'valid_label']; yield 'Pis' => [new vs\Pis(), '120.0340.678-8']; yield 'PolishIdCard' => [new vs\PolishIdCard(), 'AYW036733']; yield 'PortugueseNif' => [new vs\PortugueseNif(), '123456789']; yield 'Positive' => [new vs\Positive(), 1]; yield 'PostalCode' => [new vs\PostalCode('US'), '12345']; - yield 'PrimeNumber' => [new vs\PrimeNumber(), 7]; yield 'Printable' => [new vs\Printable(), 'abc123!@#']; yield 'Property' => [new vs\Property('age', new vs\IntVal()), (object) ['age' => 18]]; yield 'PropertyExists' => [new vs\PropertyExists('age'), (object) ['age' => 18]]; @@ -175,12 +169,10 @@ public static function provideValidatorInput(): Generator yield 'Undef' => [new vs\Undef(), null]; yield 'UndefOr' => [new vs\UndefOr(new vs\IntVal()), null]; yield 'Unique' => [new vs\Unique(), [1, 2, 3]]; - yield 'Uploaded' => [new vs\Uploaded(), 'tests/fixtures/valid-image.png']; yield 'Uppercase' => [new vs\Uppercase(), 'ABC']; yield 'Url' => [new vs\Url(), 'https://example.com']; yield 'Uuid' => [new vs\Uuid(), '123e4567-e89b-12d3-a456-426655440000']; yield 'Version' => [new vs\Version(), '1.2.3']; - yield 'VideoUrl' => [new vs\VideoUrl(), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ']; yield 'Vowel' => [new vs\Vowel(), 'aeiou']; yield 'When' => [new vs\When(new vs\IntVal(), new vs\AlwaysValid(), new vs\AlwaysInvalid()), 5]; yield 'Writable' => [new vs\Writable(), 'tests/fixtures/valid-image.png']; diff --git a/tests/unit/Validators/FibonacciTest.php b/tests/unit/Validators/FibonacciTest.php deleted file mode 100644 index 87568c7ab..000000000 --- a/tests/unit/Validators/FibonacciTest.php +++ /dev/null @@ -1,66 +0,0 @@ - - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Samuel Heinzmann - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use Respect\Validation\Test\RuleTestCase; - -#[Group('validator')] -#[CoversClass(Fibonacci::class)] -final class FibonacciTest extends RuleTestCase -{ - /** @return iterable */ - public static function providerForValidInput(): iterable - { - $validator = new Fibonacci(); - - return [ - [$validator, 1], - [$validator, 2], - [$validator, 3], - [$validator, 5], - [$validator, 8.0], - [$validator, '3'], - [$validator, 21], - [$validator, 21.0], - [$validator, '21.0'], - [$validator, 34], - [$validator, '34'], - [$validator, 1346269], - [$validator, 10610209857723], - ]; - } - - /** @return iterable */ - public static function providerForInvalidInput(): iterable - { - $validator = new Fibonacci(); - - return [ - [$validator, 0], - [$validator, 1346268], - [$validator, ''], - [$validator, null], - [$validator, 7], - [$validator, -1], - [$validator, 5.2], - [$validator, '-1'], - [$validator, 'a'], - [$validator, ' '], - [$validator, false], - [$validator, true], - ]; - } -} diff --git a/tests/unit/Validators/FilterVarTest.php b/tests/unit/Validators/FilterVarTest.php deleted file mode 100644 index 85645fe81..000000000 --- a/tests/unit/Validators/FilterVarTest.php +++ /dev/null @@ -1,72 +0,0 @@ - - * SPDX-FileContributor: Chris Ramakers - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Gabriel Caruso - * SPDX-FileContributor: Henrique Moody - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use PHPUnit\Framework\Attributes\Test; -use Respect\Validation\Exceptions\InvalidValidatorException; -use Respect\Validation\Test\RuleTestCase; - -use const FILTER_FLAG_HOSTNAME; -use const FILTER_FLAG_QUERY_REQUIRED; -use const FILTER_SANITIZE_EMAIL; -use const FILTER_VALIDATE_BOOLEAN; -use const FILTER_VALIDATE_DOMAIN; -use const FILTER_VALIDATE_EMAIL; -use const FILTER_VALIDATE_FLOAT; -use const FILTER_VALIDATE_INT; -use const FILTER_VALIDATE_URL; - -#[Group('validator')] -#[CoversClass(FilterVar::class)] -final class FilterVarTest extends RuleTestCase -{ - #[Test] - public function itShouldThrowsExceptionWhenFilterIsNotValid(): void - { - $this->expectException(InvalidValidatorException::class); - $this->expectExceptionMessage('Cannot accept the given filter'); - - new FilterVar(FILTER_SANITIZE_EMAIL); - } - - /** @return iterable */ - public static function providerForValidInput(): iterable - { - return [ - [new FilterVar(FILTER_VALIDATE_INT), '12345'], - [new FilterVar(FILTER_VALIDATE_EMAIL), 'example@example.com'], - [new FilterVar(FILTER_VALIDATE_FLOAT), 1.5], - [new FilterVar(FILTER_VALIDATE_BOOLEAN), 'On'], - [new FilterVar(FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED), 'http://example.com?foo=bar'], - [new FilterVar(FILTER_VALIDATE_DOMAIN), 'example.com'], - [new FilterVar(FILTER_VALIDATE_INT), '0'], - ]; - } - - /** @return iterable */ - public static function providerForInvalidInput(): iterable - { - return [ - [new FilterVar(FILTER_VALIDATE_INT), 1.4], - [new FilterVar(FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED), 'http://example.com'], - [new FilterVar(FILTER_VALIDATE_DOMAIN), '.com'], - [new FilterVar(FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME), '@local'], - [new FilterVar(FILTER_VALIDATE_INT, []), 1.4], - [new FilterVar(FILTER_VALIDATE_INT, 2), 1.4], - ]; - } -} diff --git a/tests/unit/Validators/PerfectSquareTest.php b/tests/unit/Validators/PerfectSquareTest.php deleted file mode 100644 index cc0821c0b..000000000 --- a/tests/unit/Validators/PerfectSquareTest.php +++ /dev/null @@ -1,64 +0,0 @@ - - * SPDX-FileContributor: Danilo Benevides - * SPDX-FileContributor: Gabriel Caruso - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Kleber Hamada Sato - * SPDX-FileContributor: Nick Lombard - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use Respect\Validation\Test\RuleTestCase; - -#[Group('validator')] -#[CoversClass(PerfectSquare::class)] -final class PerfectSquareTest extends RuleTestCase -{ - /** @return iterable */ - public static function providerForValidInput(): iterable - { - $validator = new PerfectSquare(); - - return [ - [$validator, 1], - [$validator, 9], - [$validator, 25], - [$validator, '25'], - [$validator, 400], - [$validator, '400'], - [$validator, '0'], - [$validator, 81], - [$validator, 0], - [$validator, 2500], - ]; - } - - /** @return iterable */ - public static function providerForInvalidInput(): iterable - { - $validator = new PerfectSquare(); - - return [ - [$validator, 250], - [$validator, ''], - [$validator, null], - [$validator, 7], - [$validator, -1], - [$validator, 6], - [$validator, 2], - [$validator, '-1'], - [$validator, 'a'], - [$validator, ' '], - [$validator, 'Foo'], - ]; - } -} diff --git a/tests/unit/Validators/PhpLabelTest.php b/tests/unit/Validators/PhpLabelTest.php deleted file mode 100644 index 5fa05d000..000000000 --- a/tests/unit/Validators/PhpLabelTest.php +++ /dev/null @@ -1,74 +0,0 @@ - - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Emmerson - * SPDX-FileContributor: Henrique Moody - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use DateTime; -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use Respect\Validation\Test\RuleTestCase; -use stdClass; - -use function mb_strtoupper; -use function mt_rand; -use function random_int; -use function uniqid; - -#[Group('validator')] -#[CoversClass(PhpLabel::class)] -final class PhpLabelTest extends RuleTestCase -{ - /** @return iterable */ - public static function providerForValidInput(): iterable - { - $validator = new PhpLabel(); - - return [ - [$validator, '_'], - [$validator, 'foo'], - [$validator, 'f00'], - [$validator, uniqid('_')], - [$validator, uniqid('a')], - [$validator, mb_strtoupper(uniqid('_'))], - [$validator, mb_strtoupper(uniqid('a'))], - ]; - } - - /** @return iterable */ - public static function providerForInvalidInput(): iterable - { - $validator = new PhpLabel(); - - return [ - [$validator, '%'], - [$validator, '*'], - [$validator, '-'], - [$validator, 'f-o-o-'], - [$validator, "\n"], - [$validator, "\r"], - [$validator, "\t"], - [$validator, ' '], - [$validator, 'f o o'], - [$validator, '0ne'], - [$validator, '0_ne'], - [$validator, uniqid((string) random_int(0, 9))], - [$validator, null], - [$validator, mt_rand()], - [$validator, 0], - [$validator, 1], - [$validator, []], - [$validator, new stdClass()], - [$validator, new DateTime()], - ]; - } -} diff --git a/tests/unit/Validators/PrimeNumberTest.php b/tests/unit/Validators/PrimeNumberTest.php deleted file mode 100644 index 47326202a..000000000 --- a/tests/unit/Validators/PrimeNumberTest.php +++ /dev/null @@ -1,62 +0,0 @@ - - * SPDX-FileContributor: Gabriel Caruso - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Ismael Elias - * SPDX-FileContributor: Kleber Hamada Sato - * SPDX-FileContributor: Nick Lombard - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use Respect\Validation\Test\RuleTestCase; - -#[Group('validator')] -#[CoversClass(PrimeNumber::class)] -final class PrimeNumberTest extends RuleTestCase -{ - /** @return iterable */ - public static function providerForValidInput(): iterable - { - $validator = new PrimeNumber(); - - return [ - [$validator, 3], - [$validator, 5], - [$validator, 7], - [$validator, '3'], - [$validator, '5'], - [$validator, '+7'], - ]; - } - - /** @return iterable */ - public static function providerForInvalidInput(): iterable - { - $validator = new PrimeNumber(); - - return [ - [$validator, ''], - [$validator, null], - [$validator, 0], - [$validator, 10], - [$validator, 25], - [$validator, 36], - [$validator, -1], - [$validator, '-1'], - [$validator, '25'], - [$validator, '0'], - [$validator, 'a'], - [$validator, ' '], - [$validator, 'Foo'], - ]; - } -} diff --git a/tests/unit/Validators/UploadedTest.php b/tests/unit/Validators/UploadedTest.php deleted file mode 100644 index 639628ba7..000000000 --- a/tests/unit/Validators/UploadedTest.php +++ /dev/null @@ -1,59 +0,0 @@ - - * SPDX-FileContributor: Gabriel Caruso - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: paul karikari - * SPDX-FileContributor: v0idpwn - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use PHPUnit\Framework\Attributes\Test; -use Respect\Validation\Test\Stubs\UploadedFileStub; -use Respect\Validation\Test\TestCase; -use SplFileInfo; - -#[Group('validator')] -#[CoversClass(Uploaded::class)] -final class UploadedTest extends TestCase -{ - public const string UPLOADED_FILENAME = 'uploaded.ext'; - - #[Test] - public function itShouldValidateWhenFileIsUploadedAndTheInputIsString(): void - { - set_mock_is_uploaded_file_return(true); - - self::assertValidInput(new Uploaded(), self::UPLOADED_FILENAME); - } - - #[Test] - public function itShouldValidateWhenFileIsUploadedAndTheInputIsSplFileInfo(): void - { - set_mock_is_uploaded_file_return(true); - - self::assertValidInput(new Uploaded(), new SplFileInfo(self::UPLOADED_FILENAME)); - } - - #[Test] - public function itShouldValidateWhenFileIsUploadedAndTheInputIsUploadedFile(): void - { - self::assertValidInput(new Uploaded(), UploadedFileStub::create()); - } - - #[Test] - public function itShouldInvalidateWhenFileHasNotBeenUploaded(): void - { - set_mock_is_uploaded_file_return(false); - - self::assertInvalidInput(new Uploaded(), self::UPLOADED_FILENAME); - } -} diff --git a/tests/unit/Validators/VideoUrlTest.php b/tests/unit/Validators/VideoUrlTest.php deleted file mode 100644 index 3e9779378..000000000 --- a/tests/unit/Validators/VideoUrlTest.php +++ /dev/null @@ -1,79 +0,0 @@ - - * SPDX-FileContributor: Danilo Correa - * SPDX-FileContributor: Emmerson Siqueira - * SPDX-FileContributor: Gabriel Caruso - * SPDX-FileContributor: Henrique Moody - * SPDX-FileContributor: Ricardo Gobbo - */ - -declare(strict_types=1); - -namespace Respect\Validation\Validators; - -use PHPUnit\Framework\Attributes\CoversClass; -use PHPUnit\Framework\Attributes\Group; -use PHPUnit\Framework\Attributes\Test; -use Respect\Validation\Exceptions\InvalidValidatorException; -use Respect\Validation\Test\RuleTestCase; - -#[Group('validator')] -#[CoversClass(VideoUrl::class)] -final class VideoUrlTest extends RuleTestCase -{ - #[Test] - public function itShouldThrowsExceptionWhenVideoUrlIsNotValid(): void - { - $this->expectException(InvalidValidatorException::class); - $this->expectExceptionMessage('"tiktok" is not a recognized video service.'); - - new VideoUrl('tiktok'); - } - - /** @return iterable */ - public static function providerForValidInput(): iterable - { - return [ - 'vimeo service with subdomain' => [new VideoUrl('vimeo'), 'https://player.vimeo.com/video/71787467'], - 'vimeo service url' => [new VideoUrl('vimeo'), 'https://vimeo.com/71787467'], - 'youtube service embed' => [new VideoUrl('youtube'), 'https://www.youtube.com/embed/netHLn9TScY'], - 'youtube service url' => [new VideoUrl('youtube'), 'https://www.youtube.com/watch?v=netHLn9TScY'], - 'youtube service short url' => [new VideoUrl('youtube'), 'https://youtu.be/netHLn9TScY'], - 'no service, vimeo with subdomain' => [new VideoUrl(), 'https://player.vimeo.com/video/71787467'], - 'no service, vimeo url' => [new VideoUrl(), 'https://vimeo.com/71787467'], - 'no service, youtube embed' => [new VideoUrl(), 'https://www.youtube.com/embed/netHLn9TScY'], - 'no service, youtube url' => [new VideoUrl(), 'https://www.youtube.com/watch?v=netHLn9TScY'], - 'no service, youtube short url' => [new VideoUrl(), 'https://youtu.be/netHLn9TScY'], - 'twitch video' => [new VideoUrl('twitch'), 'https://www.twitch.tv/videos/320689092'], - 'twitch clip' => [new VideoUrl('twitch'), 'https://clips.twitch.tv/BitterLazyMangetoutHumbleLife'], - ]; - } - - /** @return iterable */ - public static function providerForInvalidInput(): iterable - { - return [ - 'vimeo service with invalid URL' => [new VideoUrl('vimeo'), 1], - 'vimeo service with youtube url' => [new VideoUrl('vimeo'), 'https://www.youtube.com/watch?v=netHLn9TScY'], - 'youtube service with vimeo url' => [new VideoUrl('youtube'), 'https://vimeo.com/71787467'], - 'no service with example.com url' => [new VideoUrl(), 'example.com'], - 'no service with ftp://youtu.be/netHLn9TScY url' => [new VideoUrl(), 'ftp://youtu.be/netHLn9TScY'], - 'no service with https:/example.com/ url' => [new VideoUrl(), 'https:/example.com/'], - 'no service with https:/youtube.com/ url' => [new VideoUrl(), 'https:/youtube.com/'], - 'no service with https://vimeo' => [new VideoUrl(), 'https://vimeo'], - 'no service with https://vimeo.com71787467' => [new VideoUrl(), 'https://vimeo.com71787467'], - 'no service with https://www.google.com url ' => [new VideoUrl(), 'https://www.google.com'], - 'no service and value tel:+1-816-555-1212' => [new VideoUrl(), 'tel:+1-816-555-1212'], - 'no service and value text' => [new VideoUrl(), 'text'], - 'invalid twitch link without video identifier' => [new VideoUrl(), 'https://twitch.tv/'], - 'invalid twitch clip' => [new VideoUrl(), 'https://www.twitch.tv/yabbadabbado'], - 'invalid twitch link' => [new VideoUrl(), 'https://clips.twitch.tv/videos/90210'], - 'invalid twitch clip identifier' => [new VideoUrl(), 'https://clips.twitch.tv/90210'], - 'twitch clip without identifier' => [new VideoUrl(), 'https://clips.twitch.tv/'], - ]; - } -}