diff --git a/bin/create-mixin b/bin/create-mixin index 81b2fd94d..5828c81f8 100755 --- a/bin/create-mixin +++ b/bin/create-mixin @@ -26,7 +26,7 @@ use Respect\Validation\Mixins\NotBuilder; use Respect\Validation\Mixins\NullOrBuilder; use Respect\Validation\Mixins\PropertyBuilder; use Respect\Validation\Mixins\UndefOrBuilder; -use Respect\Validation\Rules\NotUndef; +use Respect\Validation\Rules\Undef; use Respect\Validation\Rules\NullOr; use Respect\Validation\Rules\UndefOr; use Respect\Validation\Rule; @@ -172,10 +172,10 @@ function overwriteFile(string $content, string $basename): void ['Length', 'length', $numberRelatedRules, []], ['Max', 'max', $numberRelatedRules, []], ['Min', 'min', $numberRelatedRules, []], - ['Not', 'not', [], ['Not', 'NotEmpty', 'NotEmoji', 'NotUndef', 'NullOr', 'UndefOr', 'Attributes', 'Templated', 'Named']], - ['NullOr', 'nullOr', [], ['NullOr', 'Blank', 'NotUndef', 'UndefOr', 'Templated', 'Named']], + ['Not', 'not', [], ['Not', 'NotEmpty', 'NotEmoji', 'NullOr', 'UndefOr', 'Attributes', 'Templated', 'Named']], + ['NullOr', 'nullOr', [], ['NullOr', 'Blank', 'Undef', 'UndefOr', 'Templated', 'Named']], ['Property', 'property', [], $structureRelatedRules], - ['UndefOr', 'undefOr', [], ['NullOr', 'Blank', 'NotUndef', 'UndefOr', 'Attributes', 'Templated', 'Named']], + ['UndefOr', 'undefOr', [], ['NullOr', 'Blank', 'Undef', 'UndefOr', 'Attributes', 'Templated', 'Named']], ['', null, [], []], ]; diff --git a/docs/09-list-of-rules-by-category.md b/docs/09-list-of-rules-by-category.md index 1bc36253a..c42be628e 100644 --- a/docs/09-list-of-rules-by-category.md +++ b/docs/09-list-of-rules-by-category.md @@ -163,8 +163,8 @@ - [FilterVar](rules/FilterVar.md) - [Named](rules/Named.md) - [NotEmpty](rules/NotEmpty.md) -- [NotUndef](rules/NotUndef.md) - [Templated](rules/Templated.md) +- [Undef](rules/Undef.md) ## Nesting @@ -406,7 +406,6 @@ - [Not](rules/Not.md) - [NotEmoji](rules/NotEmoji.md) - [NotEmpty](rules/NotEmpty.md) -- [NotUndef](rules/NotUndef.md) - [NoWhitespace](rules/NoWhitespace.md) - [NullOr](rules/NullOr.md) - [NullType](rules/NullType.md) @@ -451,6 +450,7 @@ - [Tld](rules/Tld.md) - [TrueVal](rules/TrueVal.md) - [Type](rules/Type.md) +- [Undef](rules/Undef.md) - [UndefOr](rules/UndefOr.md) - [Unique](rules/Unique.md) - [Uploaded](rules/Uploaded.md) diff --git a/docs/rules/Attributes.md b/docs/rules/Attributes.md index 54325236d..4cbc43098 100644 --- a/docs/rules/Attributes.md +++ b/docs/rules/Attributes.md @@ -10,8 +10,8 @@ Example of object: use Respect\Validation\Rules as Rule; #[Rule\AnyOf( - new Rule\Property('email', new Rule\NotUndef()), - new Rule\Property('phone', new Rule\NotUndef()), + new Rule\Property('email', new Rule\Not(new Rule\Undef())), + new Rule\Property('phone', new Rule\Not(new Rule\Undef())), )] final class Person { diff --git a/docs/rules/Blank.md b/docs/rules/Blank.md index 343ec7406..113a6916c 100644 --- a/docs/rules/Blank.md +++ b/docs/rules/Blank.md @@ -56,8 +56,8 @@ It's similar to [NotEmpty](NotEmpty.md), but way stricter. See also: - [NotEmpty](NotEmpty.md) -- [NotUndef](NotUndef.md) - [NoWhitespace](NoWhitespace.md) - [NullType](NullType.md) - [Number](Number.md) +- [Undef](Undef.md) - [UndefOr](UndefOr.md) diff --git a/docs/rules/NoWhitespace.md b/docs/rules/NoWhitespace.md index 82db7d118..a110c8c0d 100644 --- a/docs/rules/NoWhitespace.md +++ b/docs/rules/NoWhitespace.md @@ -45,5 +45,5 @@ See also: - [Blank](Blank.md) - [CreditCard](CreditCard.md) - [NotEmpty](NotEmpty.md) -- [NotUndef](NotUndef.md) +- [Undef](Undef.md) - [UndefOr](UndefOr.md) diff --git a/docs/rules/NotEmpty.md b/docs/rules/NotEmpty.md index e70ab6500..a6b6054f6 100644 --- a/docs/rules/NotEmpty.md +++ b/docs/rules/NotEmpty.md @@ -68,8 +68,8 @@ See also: - [Each](Each.md) - [Max](Max.md) - [Min](Min.md) -- [NotUndef](NotUndef.md) - [NoWhitespace](NoWhitespace.md) - [NullType](NullType.md) - [Number](Number.md) +- [Undef](Undef.md) - [UndefOr](UndefOr.md) diff --git a/docs/rules/NotUndef.md b/docs/rules/NotUndef.md deleted file mode 100644 index 7fd0c4d17..000000000 --- a/docs/rules/NotUndef.md +++ /dev/null @@ -1,67 +0,0 @@ -# NotUndef - -- `NotUndef()` - -Validates if the given input is not optional. By _optional_ we consider `null` -or an empty string (`''`). - -```php -v::notUndef()->isValid(''); // false -v::notUndef()->isValid(null); // false -``` - -Other values: - -```php -v::notUndef()->isValid([]); // true -v::notUndef()->isValid(' '); // true -v::notUndef()->isValid(0); // true -v::notUndef()->isValid('0'); // true -v::notUndef()->isValid(0); // true -v::notUndef()->isValid('0.0'); // true -v::notUndef()->isValid(false); // true -v::notUndef()->isValid(['']); // true -v::notUndef()->isValid([' ']); // true -v::notUndef()->isValid([0]); // true -v::notUndef()->isValid(['0']); // true -v::notUndef()->isValid([false]); // true -v::notUndef()->isValid([[''), [0]]); // true -v::notUndef()->isValid(new stdClass()); // true -``` - -## Templates - -### `NotUndef::TEMPLATE_STANDARD` - -| Mode | Template | -| ---------- | ----------------------------- | -| `default` | {{subject}} must be defined | -| `inverted` | {{subject}} must be undefined | - -## Template placeholders - -| Placeholder | Description | -| ----------- | ---------------------------------------------------------------- | -| `subject` | The validated input or the custom validator name (if specified). | - -## Categorization - -- Miscellaneous - -## Changelog - -| Version | Description | -| ------: | ---------------------------------------- | -| 3.0.0 | Renamed from "NotOptional" to "NotUndef" | -| 1.0.0 | Created | - ---- - -See also: - -- [Blank](Blank.md) -- [NotEmpty](NotEmpty.md) -- [NoWhitespace](NoWhitespace.md) -- [NullType](NullType.md) -- [Number](Number.md) -- [UndefOr](UndefOr.md) diff --git a/docs/rules/NullType.md b/docs/rules/NullType.md index d41bdac7b..10ebdc940 100644 --- a/docs/rules/NullType.md +++ b/docs/rules/NullType.md @@ -46,7 +46,6 @@ See also: - [FloatType](FloatType.md) - [IntType](IntType.md) - [NotEmpty](NotEmpty.md) -- [NotUndef](NotUndef.md) - [NullOr](NullOr.md) - [Number](Number.md) - [ObjectType](ObjectType.md) @@ -54,4 +53,5 @@ See also: - [StringType](StringType.md) - [StringVal](StringVal.md) - [Type](Type.md) +- [Undef](Undef.md) - [UndefOr](UndefOr.md) diff --git a/docs/rules/Number.md b/docs/rules/Number.md index 079335942..12105700e 100644 --- a/docs/rules/Number.md +++ b/docs/rules/Number.md @@ -48,10 +48,10 @@ See also: - [FloatType](FloatType.md) - [IntType](IntType.md) - [NotEmpty](NotEmpty.md) -- [NotUndef](NotUndef.md) - [NullType](NullType.md) - [NumericVal](NumericVal.md) - [ObjectType](ObjectType.md) - [ResourceType](ResourceType.md) - [StringType](StringType.md) - [Type](Type.md) +- [Undef](Undef.md) diff --git a/docs/rules/Undef.md b/docs/rules/Undef.md new file mode 100644 index 000000000..c0fe59e71 --- /dev/null +++ b/docs/rules/Undef.md @@ -0,0 +1,65 @@ +# Undef + +- `Undef()` + +Validates if the given input is undefined. By _undefined_ we consider `null` or an empty string (`''`). + +```php +v::undef()->isValid(''); // true +v::undef()->isValid(null); // true +``` + +Other values similar to _undefined_ values are considered _defined_: + +```php +v::undef()->isValid([]); // false +v::undef()->isValid(' '); // false +v::undef()->isValid(0); // false +v::undef()->isValid('0'); // false +v::undef()->isValid('0.0'); // false +v::undef()->isValid(false); // false +v::undef()->isValid(['']); // false +v::undef()->isValid([' ']); // false +v::undef()->isValid([0]); // false +v::undef()->isValid(['0']); // false +v::undef()->isValid([false]); // false +v::undef()->isValid([[''], [0]]); // false +v::undef()->isValid(new stdClass()); // false +``` + +## Templates + +### `Undef::TEMPLATE_STANDARD` + +| Mode | Template | +| ---------- | ----------------------------- | +| `default` | {{subject}} must be undefined | +| `inverted` | {{subject}} must be defined | + +## Template placeholders + +| Placeholder | Description | +| ----------- | ---------------------------------------------------------------- | +| `subject` | The validated input or the custom validator name (if specified). | + +## Categorization + +- Miscellaneous + +## Changelog + +| Version | Description | +| ------: | ------------------------------------------- | +| 3.0.0 | Renamed to `Undef` and changed the behavior | +| 1.0.0 | Created as `NotOptional` | + +--- + +See also: + +- [Blank](Blank.md) +- [NotEmpty](NotEmpty.md) +- [NoWhitespace](NoWhitespace.md) +- [NullType](NullType.md) +- [Number](Number.md) +- [UndefOr](UndefOr.md) diff --git a/docs/rules/UndefOr.md b/docs/rules/UndefOr.md index 3e5fd578c..f75e95cb1 100644 --- a/docs/rules/UndefOr.md +++ b/docs/rules/UndefOr.md @@ -67,7 +67,7 @@ See also: - [Blank](Blank.md) - [NotEmpty](NotEmpty.md) -- [NotUndef](NotUndef.md) - [NoWhitespace](NoWhitespace.md) - [NullOr](NullOr.md) - [NullType](NullType.md) +- [Undef](Undef.md) diff --git a/library/Mixins/Builder.php b/library/Mixins/Builder.php index 9ad3ca36c..15ddd156b 100644 --- a/library/Mixins/Builder.php +++ b/library/Mixins/Builder.php @@ -248,8 +248,6 @@ public static function notEmoji(): Chain; public static function notEmpty(): Chain; - public static function notUndef(): Chain; - public static function nullOr(Rule $rule): Chain; public static function nullType(): Chain; @@ -337,6 +335,8 @@ public static function tld(): Chain; public static function trueVal(): Chain; + public static function undef(): Chain; + public static function undefOr(Rule $rule): Chain; public static function unique(): Chain; diff --git a/library/Mixins/Chain.php b/library/Mixins/Chain.php index 1e5996f1d..1b61daa2a 100644 --- a/library/Mixins/Chain.php +++ b/library/Mixins/Chain.php @@ -251,8 +251,6 @@ public function notEmoji(): Chain; public function notEmpty(): Chain; - public function notUndef(): Chain; - public function nullOr(Rule $rule): Chain; public function nullType(): Chain; @@ -340,6 +338,8 @@ public function tld(): Chain; public function trueVal(): Chain; + public function undef(): Chain; + public function undefOr(Rule $rule): Chain; public function unique(): Chain; diff --git a/library/Mixins/KeyBuilder.php b/library/Mixins/KeyBuilder.php index 590271ccf..6f4af1b8d 100644 --- a/library/Mixins/KeyBuilder.php +++ b/library/Mixins/KeyBuilder.php @@ -227,8 +227,6 @@ public static function keyNotEmoji(int|string $key): Chain; public static function keyNotEmpty(int|string $key): Chain; - public static function keyNotUndef(int|string $key): Chain; - public static function keyNullType(int|string $key): Chain; public static function keyNumber(int|string $key): Chain; @@ -305,6 +303,8 @@ public static function keyTld(int|string $key): Chain; public static function keyTrueVal(int|string $key): Chain; + public static function keyUndef(int|string $key): Chain; + public static function keyUnique(int|string $key): Chain; public static function keyUploaded(int|string $key): Chain; diff --git a/library/Mixins/KeyChain.php b/library/Mixins/KeyChain.php index c19b5fb48..55689aa08 100644 --- a/library/Mixins/KeyChain.php +++ b/library/Mixins/KeyChain.php @@ -227,8 +227,6 @@ public function keyNotEmoji(int|string $key): Chain; public function keyNotEmpty(int|string $key): Chain; - public function keyNotUndef(int|string $key): Chain; - public function keyNullType(int|string $key): Chain; public function keyNumber(int|string $key): Chain; @@ -305,6 +303,8 @@ public function keyTld(int|string $key): Chain; public function keyTrueVal(int|string $key): Chain; + public function keyUndef(int|string $key): Chain; + public function keyUnique(int|string $key): Chain; public function keyUploaded(int|string $key): Chain; diff --git a/library/Mixins/NotBuilder.php b/library/Mixins/NotBuilder.php index 799ac4c05..b50a58d9a 100644 --- a/library/Mixins/NotBuilder.php +++ b/library/Mixins/NotBuilder.php @@ -311,6 +311,8 @@ public static function notTld(): Chain; public static function notTrueVal(): Chain; + public static function notUndef(): Chain; + public static function notUnique(): Chain; public static function notUploaded(): Chain; diff --git a/library/Mixins/NotChain.php b/library/Mixins/NotChain.php index 206cb096b..50bcfee23 100644 --- a/library/Mixins/NotChain.php +++ b/library/Mixins/NotChain.php @@ -311,6 +311,8 @@ public function notTld(): Chain; public function notTrueVal(): Chain; + public function notUndef(): Chain; + public function notUnique(): Chain; public function notUploaded(): Chain; diff --git a/library/Mixins/PropertyBuilder.php b/library/Mixins/PropertyBuilder.php index 7ea492a99..f63bd1a7c 100644 --- a/library/Mixins/PropertyBuilder.php +++ b/library/Mixins/PropertyBuilder.php @@ -231,8 +231,6 @@ public static function propertyNotEmoji(string $propertyName): Chain; public static function propertyNotEmpty(string $propertyName): Chain; - public static function propertyNotUndef(string $propertyName): Chain; - public static function propertyNullType(string $propertyName): Chain; public static function propertyNumber(string $propertyName): Chain; @@ -313,6 +311,8 @@ public static function propertyTld(string $propertyName): Chain; public static function propertyTrueVal(string $propertyName): Chain; + public static function propertyUndef(string $propertyName): Chain; + public static function propertyUnique(string $propertyName): Chain; public static function propertyUploaded(string $propertyName): Chain; diff --git a/library/Mixins/PropertyChain.php b/library/Mixins/PropertyChain.php index 5148f81a4..40f95eaf3 100644 --- a/library/Mixins/PropertyChain.php +++ b/library/Mixins/PropertyChain.php @@ -227,8 +227,6 @@ public function propertyNotEmoji(string $propertyName): Chain; public function propertyNotEmpty(string $propertyName): Chain; - public function propertyNotUndef(string $propertyName): Chain; - public function propertyNullType(string $propertyName): Chain; public function propertyNumber(string $propertyName): Chain; @@ -305,6 +303,8 @@ public function propertyTld(string $propertyName): Chain; public function propertyTrueVal(string $propertyName): Chain; + public function propertyUndef(string $propertyName): Chain; + public function propertyUnique(string $propertyName): Chain; public function propertyUploaded(string $propertyName): Chain; diff --git a/library/Rules/NotUndef.php b/library/Rules/Undef.php similarity index 83% rename from library/Rules/NotUndef.php rename to library/Rules/Undef.php index 0cee0e1c7..d14d3f366 100644 --- a/library/Rules/NotUndef.php +++ b/library/Rules/Undef.php @@ -17,15 +17,15 @@ #[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)] #[Template( - '{{subject}} must be defined', '{{subject}} must be undefined', + '{{subject}} must be defined', )] -final class NotUndef implements Rule +final class Undef implements Rule { use CanValidateUndefined; public function evaluate(mixed $input): Result { - return Result::of($this->isUndefined($input) === false, $input, $this); + return Result::of($this->isUndefined($input), $input, $this); } } diff --git a/library/Transformers/Prefix.php b/library/Transformers/Prefix.php index 5e1b70b07..c22c8b1c7 100644 --- a/library/Transformers/Prefix.php +++ b/library/Transformers/Prefix.php @@ -29,7 +29,7 @@ final class Prefix implements Transformer 'not', 'notEmoji', 'notEmpty', - 'notUndef', + 'undef', 'nullOr', 'property', 'propertyExists', diff --git a/tests/feature/Rules/NotUndefTest.php b/tests/feature/Rules/NotUndefTest.php deleted file mode 100644 index 2ed8fecad..000000000 --- a/tests/feature/Rules/NotUndefTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * SPDX-License-Identifier: MIT - */ - -declare(strict_types=1); - -test('Scenario #1', catchMessage( - fn() => v::notUndef()->assert(null), - fn(string $message) => expect($message)->toBe('`null` must be defined'), -)); - -test('Scenario #2', catchMessage( - fn() => v::not(v::notUndef())->assert(0), - fn(string $message) => expect($message)->toBe('0 must be undefined'), -)); - -test('Scenario #3', catchMessage( - fn() => v::notUndef()->setName('Field')->assert(null), - fn(string $message) => expect($message)->toBe('Field must be defined'), -)); - -test('Scenario #4', catchMessage( - fn() => v::not(v::notUndef()->setName('Field'))->assert([]), - fn(string $message) => expect($message)->toBe('Field must be undefined'), -)); - -test('Scenario #5', catchFullMessage( - fn() => v::notUndef()->assert(''), - fn(string $fullMessage) => expect($fullMessage)->toBe('- "" must be defined'), -)); - -test('Scenario #6', catchFullMessage( - fn() => v::not(v::notUndef())->assert([]), - fn(string $fullMessage) => expect($fullMessage)->toBe('- `[]` must be undefined'), -)); - -test('Scenario #7', catchFullMessage( - fn() => v::notUndef()->setName('Field')->assert(''), - fn(string $fullMessage) => expect($fullMessage)->toBe('- Field must be defined'), -)); - -test('Scenario #8', catchFullMessage( - fn() => v::not(v::notUndef()->setName('Field'))->assert([]), - fn(string $fullMessage) => expect($fullMessage)->toBe('- Field must be undefined'), -)); diff --git a/tests/feature/Rules/UndefTest.php b/tests/feature/Rules/UndefTest.php new file mode 100644 index 000000000..08883b4d4 --- /dev/null +++ b/tests/feature/Rules/UndefTest.php @@ -0,0 +1,24 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('default template', catchAll( + fn() => v::undef()->assert(false), + fn(string $message, string $fullMessage, array $messages) => expect() + ->and($message)->toBe('`false` must be undefined') + ->and($fullMessage)->toBe('- `false` must be undefined') + ->and($messages)->toBe(['undef' => '`false` must be undefined']), +)); + +test('inverted template', catchAll( + fn() => v::not(v::undef())->assert(null), + fn(string $message, string $fullMessage, array $messages) => expect() + ->and($message)->toBe('`null` must be defined') + ->and($fullMessage)->toBe('- `null` must be defined') + ->and($messages)->toBe(['notUndef' => '`null` must be defined']), +)); diff --git a/tests/library/Stubs/WithAttributes.php b/tests/library/Stubs/WithAttributes.php index d810e17cf..5c3628f1a 100644 --- a/tests/library/Stubs/WithAttributes.php +++ b/tests/library/Stubs/WithAttributes.php @@ -12,8 +12,8 @@ use Respect\Validation\Rules as Rule; #[Rule\AnyOf( - new Rule\Property('email', new Rule\NotUndef()), - new Rule\Property('phone', new Rule\NotUndef()), + new Rule\Property('email', new Rule\Not(new Rule\Undef())), + new Rule\Property('phone', new Rule\Not(new Rule\Undef())), )] final class WithAttributes extends ParentWithAttributes { diff --git a/tests/unit/Rules/NotUndefTest.php b/tests/unit/Rules/UndefTest.php similarity index 80% rename from tests/unit/Rules/NotUndefTest.php rename to tests/unit/Rules/UndefTest.php index 9534c164b..969e3fbe9 100644 --- a/tests/unit/Rules/NotUndefTest.php +++ b/tests/unit/Rules/UndefTest.php @@ -15,13 +15,13 @@ use stdClass; #[Group('rule')] -#[CoversClass(NotUndef::class)] -final class NotUndefTest extends RuleTestCase +#[CoversClass(Undef::class)] +final class UndefTest extends RuleTestCase { - /** @return iterable */ - public static function providerForValidInput(): iterable + /** @return iterable */ + public static function providerForInvalidInput(): iterable { - $rule = new NotUndef(); + $rule = new Undef(); return [ [$rule, []], @@ -41,10 +41,10 @@ public static function providerForValidInput(): iterable ]; } - /** @return iterable */ - public static function providerForInvalidInput(): iterable + /** @return iterable */ + public static function providerForValidInput(): iterable { - $rule = new NotUndef(); + $rule = new Undef(); return [ [$rule, null], diff --git a/tests/unit/Transformers/PrefixTest.php b/tests/unit/Transformers/PrefixTest.php index 9ec6fb27d..dcf7f0bab 100644 --- a/tests/unit/Transformers/PrefixTest.php +++ b/tests/unit/Transformers/PrefixTest.php @@ -95,7 +95,7 @@ public static function providerForUntransformedRuleNames(): array 'not' => ['not'], 'notEmoji' => ['notEmoji'], 'notEmpty' => ['notEmpty'], - 'notUndef' => ['notUndef'], + 'undef' => ['undef'], 'property' => ['property'], 'propertyExists' => ['propertyExists'], 'propertyOptional' => ['propertyOptional'],