From e5ea6231e25fc4e1052328b0acfd4899a373f72d Mon Sep 17 00:00:00 2001 From: Henrique Moody Date: Fri, 13 Dec 2024 16:00:09 +0100 Subject: [PATCH] Use Pest instead of PHPT files Although I love PHPT files, and I've done my fair share of making it easier to write them in this library, they're very slow, and running them has become a hindrance. I've been fidgeting with the idea of using Pest for a while, and I think it's the right tool for the job. I had to create a couple of functions to make it easier to run those tests, and now they're working really alright. I migrated all the PHPT files into Pest files -- I automated most of the work with a little script using "nikic/php-parser"; this commit should contain all the previous PHPT tests as Pest tests. The previous integration tests would take sisten seconds, and the Pest tests take less than a second. --- .github/workflows/continuous-integration.yml | 6 +- composer.json | 15 +- library/Transformers/DeprecatedAttribute.php | 2 +- library/Transformers/DeprecatedKey.php | 2 +- phpcs.xml.dist | 8 +- phpstan.neon.dist | 26 +- phpunit.xml.dist | 4 +- tests/Pest.php | 101 +++++++ tests/{integration/lib => }/aliases.php | 0 .../AssertWithKeys.php} | 42 +-- tests/feature/AssertWithProperties.php | 54 ++++ tests/feature/AssertWithTemplates.php | 36 +++ ...edValidationExceptionInterfaceForCheck.php | 15 + ...ldIncludeAllValidationMessagesInAChain.php | 19 ++ tests/feature/GetMessages.php | 39 +++ ...ldIncludeAllValidationMessagesInAChain.php | 30 ++ tests/feature/GetMessagesWithReplacements.php | 31 +++ tests/feature/Issues/Issue1033Test.php | 25 ++ tests/feature/Issues/Issue1244Test.php | 15 + .../Issues/Issue1289Test.php} | 43 +-- tests/feature/Issues/Issue1333Test.php | 23 ++ tests/feature/Issues/Issue1334Test.php | 38 +++ tests/feature/Issues/Issue1348Test.php | 82 ++++++ tests/feature/Issues/Issue1376Test.php | 38 +++ tests/feature/Issues/Issue1469Test.php | 37 +++ tests/feature/Issues/Issue1477Test.php | 25 ++ tests/feature/Issues/Issue179Test.php | 37 +++ tests/feature/Issues/Issue425Test.php | 19 ++ tests/feature/Issues/Issue446Test.php | 23 ++ tests/feature/Issues/Issue619Test.php | 15 + tests/feature/Issues/Issue739Test.php | 15 + .../Issues/Issue796Test.php} | 44 +-- tests/feature/Issues/Issue799Test.php | 46 ++++ tests/feature/Issues/Issue805Test.php | 15 + tests/feature/KeysAsValidatorNames.php | 28 ++ tests/feature/NotWithRecursion.php | 34 +++ tests/feature/NotWithoutRecursion.php | 18 ++ tests/feature/Readme/CustomMessagesTest.php | 18 ++ .../Readme/ExampleTest.php} | 20 +- .../Readme/GettingMessagesAsAnArrayTest.php | 18 ++ tests/feature/Rules/AllOfTest.php | 71 +++++ tests/feature/Rules/AlnumTest.php | 48 ++++ tests/feature/Rules/AlphaTest.php | 48 ++++ tests/feature/Rules/AlwaysInvalidTest.php | 18 ++ tests/feature/Rules/AlwaysValidTest.php | 18 ++ tests/feature/Rules/ArrayTypeTest.php | 28 ++ tests/feature/Rules/ArrayValTest.php | 28 ++ tests/feature/Rules/AttributesTest.php | 70 +++++ tests/feature/Rules/Base64Test.php | 28 ++ tests/feature/Rules/BaseTest.php | 28 ++ tests/feature/Rules/BeetwenTest.php | 38 +++ tests/feature/Rules/BetweenExclusiveTest.php | 36 +++ tests/feature/Rules/BoolTypeTest.php | 28 ++ tests/feature/Rules/BoolValTest.php | 28 ++ tests/feature/Rules/BsnTest.php | 28 ++ tests/feature/Rules/CallTest.php | 38 +++ tests/feature/Rules/CallableTypeTest.php | 30 ++ tests/feature/Rules/CallbackTest.php | 28 ++ tests/feature/Rules/CharsetTest.php | 28 ++ tests/feature/Rules/CnhTest.php | 28 ++ tests/feature/Rules/CnpjTest.php | 30 ++ tests/feature/Rules/CntrlTest.php | 50 ++++ tests/feature/Rules/ConsecutiveTest.php | 92 +++++++ tests/feature/Rules/ConsonantTest.php | 48 ++++ tests/feature/Rules/ContainsAnyTest.php | 28 ++ tests/feature/Rules/ContainsTest.php | 28 ++ tests/feature/Rules/CountableTest.php | 28 ++ tests/feature/Rules/CountryCodeTest.php | 28 ++ tests/feature/Rules/CpfTest.php | 28 ++ tests/feature/Rules/CreditCardTest.php | 28 ++ tests/feature/Rules/CurrencyCodeTest.php | 28 ++ tests/feature/Rules/DateTest.php | 30 ++ tests/feature/Rules/DateTimeDiffTest.php | 148 ++++++++++ tests/feature/Rules/DateTimeTest.php | 50 ++++ tests/feature/Rules/DecimalTest.php | 28 ++ tests/feature/Rules/DigitTest.php | 48 ++++ tests/feature/Rules/DirectoryTest.php | 28 ++ tests/feature/Rules/DomainTest.php | 28 ++ tests/feature/Rules/EachTest.php | 241 +++++++++++++++++ tests/feature/Rules/EmailTest.php | 28 ++ tests/feature/Rules/EndsWithTest.php | 28 ++ tests/feature/Rules/EqualsTest.php | 28 ++ tests/feature/Rules/EquivalentTest.php | 28 ++ tests/feature/Rules/EvenTest.php | 28 ++ tests/feature/Rules/ExecutableTest.php | 28 ++ tests/feature/Rules/ExistsTest.php | 28 ++ tests/feature/Rules/ExtensionTest.php | 28 ++ tests/feature/Rules/FactorTest.php | 28 ++ tests/feature/Rules/FalseValTest.php | 28 ++ tests/feature/Rules/FibonacciTest.php | 28 ++ tests/feature/Rules/FileTest.php | 28 ++ tests/feature/Rules/FilterVarTest.php | 28 ++ tests/feature/Rules/FiniteTest.php | 28 ++ tests/feature/Rules/FloatTypeTest.php | 28 ++ tests/feature/Rules/FloatvalTest.php | 28 ++ tests/feature/Rules/GraphTest.php | 48 ++++ .../feature/Rules/GreaterThanOrEqualTest.php | 28 ++ tests/feature/Rules/GreaterThanTest.php | 28 ++ tests/feature/Rules/HetuTest.php | 36 +++ tests/feature/Rules/HexRgbColorTest.php | 28 ++ tests/feature/Rules/IbanTest.php | 28 ++ tests/feature/Rules/IdenticalTest.php | 28 ++ tests/feature/Rules/ImageTest.php | 28 ++ tests/feature/Rules/ImeiTest.php | 28 ++ tests/feature/Rules/InTest.php | 28 ++ tests/feature/Rules/InfiniteTest.php | 28 ++ tests/feature/Rules/InstanceTest.php | 28 ++ tests/feature/Rules/IntTypeTest.php | 28 ++ tests/feature/Rules/IntValTest.php | 38 +++ tests/feature/Rules/IpTest.php | 48 ++++ tests/feature/Rules/IsbnTest.php | 28 ++ tests/feature/Rules/IterableTypeTest.php | 36 +++ tests/feature/Rules/IterableValTest.php | 28 ++ tests/feature/Rules/JsonTest.php | 28 ++ tests/feature/Rules/KeyExistsTest.php | 36 +++ tests/feature/Rules/KeyOptionalTest.php | 78 ++++++ tests/feature/Rules/KeySetTest.php | 215 +++++++++++++++ tests/feature/Rules/KeyTest.php | 99 +++++++ tests/feature/Rules/LanguageCodeTest.php | 28 ++ tests/feature/Rules/LazyTest.php | 64 +++++ tests/feature/Rules/LeapDateTest.php | 28 ++ tests/feature/Rules/LeapYearTest.php | 28 ++ tests/feature/Rules/LengthTest.php | 43 +++ tests/feature/Rules/LessThanOrEqualTest.php | 28 ++ tests/feature/Rules/LessThanTest.php | 28 ++ tests/feature/Rules/LowercaseTest.php | 28 ++ tests/feature/Rules/LuhnTest.php | 28 ++ tests/feature/Rules/MacAddressTest.php | 28 ++ tests/feature/Rules/MaxTest.php | 71 +++++ tests/feature/Rules/MimetypeTest.php | 28 ++ tests/feature/Rules/MinTest.php | 36 +++ tests/feature/Rules/MultipleTest.php | 28 ++ tests/feature/Rules/NegativeTest.php | 28 ++ tests/feature/Rules/NfeAccessKeyTest.php | 28 ++ tests/feature/Rules/NifTest.php | 28 ++ tests/feature/Rules/NipTest.php | 30 ++ tests/feature/Rules/NoTest.php | 28 ++ tests/feature/Rules/NoWhitespaceTest.php | 28 ++ tests/feature/Rules/NoneOfTest.php | 36 +++ tests/feature/Rules/NotBlankTest.php | 38 +++ tests/feature/Rules/NotEmojiTest.php | 28 ++ tests/feature/Rules/NotEmptyTest.php | 38 +++ tests/feature/Rules/NotUndefTest.php | 48 ++++ tests/feature/Rules/NullOrTest.php | 111 ++++++++ tests/feature/Rules/NullTypeTest.php | 28 ++ tests/feature/Rules/NumberTest.php | 28 ++ tests/feature/Rules/NumericValTest.php | 28 ++ tests/feature/Rules/ObjectTypeTest.php | 28 ++ tests/feature/Rules/OddTest.php | 28 ++ tests/feature/Rules/PerfectSquareTest.php | 28 ++ tests/feature/Rules/PeselTest.php | 30 ++ tests/feature/Rules/PhoneTest.php | 43 +++ tests/feature/Rules/PhplabelTest.php | 28 ++ tests/feature/Rules/PisTest.php | 28 ++ tests/feature/Rules/PolishIdCardTest.php | 30 ++ tests/feature/Rules/PositiveTest.php | 28 ++ tests/feature/Rules/PostalCodeTest.php | 28 ++ tests/feature/Rules/PrimeNumberTest.php | 28 ++ tests/feature/Rules/PrintableTest.php | 28 ++ tests/feature/Rules/PropertyExistsTest.php | 36 +++ tests/feature/Rules/PropertyOptionalTest.php | 83 ++++++ tests/feature/Rules/PropertyTest.php | 106 ++++++++ tests/feature/Rules/PunctTest.php | 48 ++++ tests/feature/Rules/ReadableTest.php | 28 ++ tests/feature/Rules/RegexTest.php | 28 ++ tests/feature/Rules/ResourceTypeTest.php | 28 ++ tests/feature/Rules/RomanTest.php | 28 ++ tests/feature/Rules/ScalarValTest.php | 28 ++ tests/feature/Rules/SizeTest.php | 68 +++++ tests/feature/Rules/SlugTest.php | 28 ++ tests/feature/Rules/SortedTest.php | 48 ++++ tests/feature/Rules/SpaceTest.php | 48 ++++ tests/feature/Rules/StartsWithTest.php | 28 ++ tests/feature/Rules/StringTypeTest.php | 28 ++ tests/feature/Rules/StringValTest.php | 28 ++ tests/feature/Rules/SubsetTest.php | 28 ++ tests/feature/Rules/SymbolicLinkTest.php | 28 ++ tests/feature/Rules/TimeTest.php | 30 ++ tests/feature/Rules/TldTest.php | 28 ++ tests/feature/Rules/TrueValTest.php | 28 ++ tests/feature/Rules/UndefOrTest.php | 111 ++++++++ tests/feature/Rules/UniqueTest.php | 28 ++ tests/feature/Rules/UploadedTest.php | 40 +++ tests/feature/Rules/UppercaseTest.php | 28 ++ tests/feature/Rules/UrlTest.php | 28 ++ tests/feature/Rules/UuidTest.php | 48 ++++ tests/feature/Rules/VersionTest.php | 28 ++ tests/feature/Rules/VideoUrlTest.php | 48 ++++ tests/feature/Rules/VowelTest.php | 48 ++++ tests/feature/Rules/WhenTest.php | 56 ++++ tests/feature/Rules/WritableTest.php | 28 ++ tests/feature/Rules/XdigitTest.php | 48 ++++ tests/feature/Rules/YesTest.php | 28 ++ ...lidatorsShouldUseTemplateAsFullMessage.php | 17 ++ ...lidatorsShouldUseTemplateAsMainMessage.php | 17 ++ ...alidatorShouldUseTemplateAsMainMessage.php | 22 ++ .../ShouldNotOverwriteDefinedNames.php | 25 ++ tests/feature/Transformers/AliasesTest.php | 17 ++ .../Transformers/DeprecatedAgeTest.php | 58 ++++ .../Transformers/DeprecatedAttributeTest.php | 60 ++++ .../Transformers/DeprecatedKeyNestedTest.php | 38 +++ .../Transformers/DeprecatedKeyTest.php | 46 ++++ .../Transformers/DeprecatedKeyValueTest.php | 68 +++++ .../Transformers/DeprecatedLengthTest.php | 154 +++++++++++ .../Transformers/DeprecatedMaxTest.php | 32 +++ .../Transformers/DeprecatedMinTest.php | 32 +++ .../Transformers/DeprecatedTypeTest.php | 80 ++++++ tests/feature/Transformers/PrefixTest.php | 66 +++++ .../Translator.php} | 31 ++- tests/integration/assert-with-properties.phpt | 48 ---- tests/integration/assert-with-templates.phpt | 84 ------ ...idation_exception_interface_for_check.phpt | 13 - ...de_all_validation_messages_in_a_chain.phpt | 13 - tests/integration/get_messages.phpt | 53 ---- ...de_all_validation_messages_in_a_chain.phpt | 32 --- .../get_messages_with_replacements.phpt | 66 ----- tests/integration/issues/1033.phpt | 24 -- tests/integration/issues/1244.phpt | 18 -- tests/integration/issues/1333.phpt | 22 -- tests/integration/issues/1334.phpt | 46 ---- tests/integration/issues/1348.phpt | 84 ------ tests/integration/issues/1376.phpt | 36 --- tests/integration/issues/1469.phpt | 50 ---- tests/integration/issues/1477.phpt | 28 -- tests/integration/issues/179.phpt | 32 --- tests/integration/issues/425.phpt | 28 -- tests/integration/issues/446.phpt | 25 -- tests/integration/issues/619.phpt | 18 -- tests/integration/issues/739.phpt | 18 -- tests/integration/issues/799.phpt | 49 ---- tests/integration/issues/805.phpt | 18 -- .../integration/keys_as_validator_names.phpt | 21 -- tests/integration/lib/helpers.php | 66 ----- .../not_should_work_by_builder.phpt | 13 - tests/integration/not_with_recursion.phpt | 25 -- tests/integration/not_without_recursion.phpt | 16 -- tests/integration/readme/custom_messages.phpt | 23 -- tests/integration/readme/example_1.phpt | 22 -- .../readme/getting_messages_as_an_array.phpt | 16 -- tests/integration/rules/allOf.phpt | 73 ----- tests/integration/rules/alnum.phpt | 23 -- tests/integration/rules/alpha.phpt | 23 -- tests/integration/rules/alwaysInvalid.phpt | 11 - tests/integration/rules/alwaysValid.phpt | 11 - tests/integration/rules/arrayType.phpt | 15 - tests/integration/rules/arrayVal.phpt | 15 - tests/integration/rules/attributes.phpt | 78 ------ tests/integration/rules/base.phpt | 15 - tests/integration/rules/base64.phpt | 15 - tests/integration/rules/beetwen.phpt | 19 -- tests/integration/rules/betweenExclusive.phpt | 44 --- tests/integration/rules/boolType.phpt | 15 - tests/integration/rules/boolVal.phpt | 15 - tests/integration/rules/bsn.phpt | 15 - tests/integration/rules/call.phpt | 19 -- tests/integration/rules/callableType.phpt | 17 -- tests/integration/rules/callback.phpt | 15 - tests/integration/rules/charset.phpt | 15 - tests/integration/rules/cnh.phpt | 15 - tests/integration/rules/cnpj.phpt | 15 - tests/integration/rules/cntrl.phpt | 23 -- tests/integration/rules/consecutive.phpt | 139 ---------- tests/integration/rules/consonant.phpt | 23 -- tests/integration/rules/contains.phpt | 15 - tests/integration/rules/containsAny.phpt | 15 - tests/integration/rules/countable.phpt | 15 - tests/integration/rules/countryCode.phpt | 15 - tests/integration/rules/cpf.phpt | 15 - tests/integration/rules/creditCard.phpt | 15 - tests/integration/rules/currencyCode.phpt | 15 - tests/integration/rules/date.phpt | 17 -- tests/integration/rules/dateTime.phpt | 25 -- tests/integration/rules/dateTimeDiff.phpt | 189 ------------- tests/integration/rules/decimal.phpt | 15 - tests/integration/rules/digit.phpt | 23 -- tests/integration/rules/directory.phpt | 15 - tests/integration/rules/domain.phpt | 15 - tests/integration/rules/each.phpt | 256 ------------------ tests/integration/rules/email.phpt | 15 - tests/integration/rules/endsWith.phpt | 15 - tests/integration/rules/equals.phpt | 15 - tests/integration/rules/equivalent.phpt | 15 - tests/integration/rules/even.phpt | 15 - tests/integration/rules/executable.phpt | 15 - tests/integration/rules/exists.phpt | 15 - tests/integration/rules/extension.phpt | 15 - tests/integration/rules/factor.phpt | 15 - tests/integration/rules/falseVal.phpt | 15 - tests/integration/rules/fibonacci.phpt | 15 - tests/integration/rules/file.phpt | 15 - tests/integration/rules/filterVar.phpt | 15 - tests/integration/rules/finite.phpt | 15 - tests/integration/rules/floatType.phpt | 15 - tests/integration/rules/floatval.phpt | 15 - tests/integration/rules/graph.phpt | 23 -- tests/integration/rules/greaterThan.phpt | 15 - .../integration/rules/greaterThanOrEqual.phpt | 15 - tests/integration/rules/hetu.phpt | 44 --- tests/integration/rules/hexRgbColor.phpt | 15 - tests/integration/rules/iban.phpt | 20 -- tests/integration/rules/identical.phpt | 15 - tests/integration/rules/image.phpt | 15 - tests/integration/rules/imei.phpt | 15 - tests/integration/rules/in.phpt | 15 - tests/integration/rules/infinite.phpt | 15 - tests/integration/rules/instance.phpt | 15 - tests/integration/rules/intType.phpt | 15 - tests/integration/rules/intVal.phpt | 19 -- tests/integration/rules/ip.phpt | 28 -- tests/integration/rules/isbn.phpt | 15 - tests/integration/rules/iterableType.phpt | 44 --- tests/integration/rules/iterableVal.phpt | 15 - tests/integration/rules/json.phpt | 15 - tests/integration/rules/key.phpt | 154 ----------- tests/integration/rules/keyExists.phpt | 44 --- tests/integration/rules/keyOptional.phpt | 121 --------- tests/integration/rules/keySet.phpt | 227 ---------------- tests/integration/rules/languageCode.phpt | 15 - tests/integration/rules/lazy.phpt | 99 ------- tests/integration/rules/leapDate.phpt | 15 - tests/integration/rules/leapYear.phpt | 15 - tests/integration/rules/length.phpt | 53 ---- tests/integration/rules/lessThan.phpt | 15 - tests/integration/rules/lessThanOrEqual.phpt | 15 - tests/integration/rules/lowercase.phpt | 15 - tests/integration/rules/luhn.phpt | 15 - tests/integration/rules/macAddress.phpt | 15 - tests/integration/rules/max.phpt | 96 ------- tests/integration/rules/mimetype.phpt | 15 - tests/integration/rules/min.phpt | 44 --- tests/integration/rules/multiple.phpt | 15 - tests/integration/rules/negative.phpt | 15 - tests/integration/rules/nfeAccessKey.phpt | 15 - tests/integration/rules/nif.phpt | 15 - tests/integration/rules/nip.phpt | 15 - tests/integration/rules/no.phpt | 15 - tests/integration/rules/noWhitespace.phpt | 15 - tests/integration/rules/noneOf.phpt | 19 -- tests/integration/rules/notBlank.phpt | 19 -- tests/integration/rules/notEmoji.phpt | 15 - tests/integration/rules/notEmpty.phpt | 19 -- tests/integration/rules/notUndef.phpt | 23 -- tests/integration/rules/nullOr.phpt | 138 ---------- tests/integration/rules/nullType.phpt | 15 - tests/integration/rules/number.phpt | 15 - tests/integration/rules/numericVal.phpt | 15 - tests/integration/rules/objectType.phpt | 15 - tests/integration/rules/odd.phpt | 15 - tests/integration/rules/perfectSquare.phpt | 15 - tests/integration/rules/pesel.phpt | 15 - tests/integration/rules/phone.phpt | 53 ---- tests/integration/rules/phplabel.phpt | 17 -- tests/integration/rules/pis.phpt | 15 - tests/integration/rules/polishIdCard.phpt | 15 - tests/integration/rules/positive.phpt | 15 - tests/integration/rules/postalCode.phpt | 15 - tests/integration/rules/primeNumber.phpt | 15 - tests/integration/rules/printable.phpt | 15 - tests/integration/rules/property.phpt | 162 ----------- tests/integration/rules/propertyExists.phpt | 44 --- tests/integration/rules/propertyOptional.phpt | 129 --------- tests/integration/rules/punct.phpt | 23 -- tests/integration/rules/readable.phpt | 15 - tests/integration/rules/regex.phpt | 15 - tests/integration/rules/resourceType.phpt | 15 - tests/integration/rules/roman.phpt | 15 - tests/integration/rules/scalarVal.phpt | 15 - tests/integration/rules/size.phpt | 31 --- tests/integration/rules/slug.phpt | 15 - tests/integration/rules/sorted.phpt | 23 -- tests/integration/rules/space.phpt | 23 -- tests/integration/rules/startsWith.phpt | 15 - tests/integration/rules/stringType.phpt | 15 - tests/integration/rules/stringVal.phpt | 15 - tests/integration/rules/subset.phpt | 15 - tests/integration/rules/symbolicLink.phpt | 15 - tests/integration/rules/time.phpt | 17 -- tests/integration/rules/tld.phpt | 15 - tests/integration/rules/trueVal.phpt | 15 - tests/integration/rules/undefOr.phpt | 138 ---------- tests/integration/rules/unique.phpt | 15 - tests/integration/rules/uploaded.phpt | 24 -- tests/integration/rules/uppercase.phpt | 15 - tests/integration/rules/url.phpt | 15 - tests/integration/rules/uuid.phpt | 23 -- tests/integration/rules/version.phpt | 15 - tests/integration/rules/videoUrl.phpt | 23 -- tests/integration/rules/vowel.phpt | 23 -- tests/integration/rules/when.phpt | 84 ------ tests/integration/rules/writable.phpt | 15 - tests/integration/rules/xdigit.phpt | 23 -- tests/integration/rules/yes.phpt | 15 - ...s_should_use_template_as_full_message.phpt | 13 - ...s_should_use_template_as_main_message.phpt | 15 - ...r_should_use_template_as_main_message.phpt | 17 -- .../should_not_overwrite_defined_names.phpt | 19 -- tests/integration/transformers/aliases.phpt | 17 -- .../transformers/deprecated_age.phpt | 41 --- .../transformers/deprecated_attribute.phpt | 43 --- .../transformers/deprecated_key.phpt | 33 --- .../transformers/deprecated_keyNested.phpt | 45 --- .../transformers/deprecated_keyValue.phpt | 47 ---- .../transformers/deprecated_length.phpt | 103 ------- .../transformers/deprecated_max.phpt | 23 -- .../transformers/deprecated_min.phpt | 23 -- .../transformers/deprecated_type.phpt | 55 ---- tests/integration/transformers/prefix.phpt | 80 ------ 407 files changed, 7747 insertions(+), 6281 deletions(-) create mode 100644 tests/Pest.php rename tests/{integration/lib => }/aliases.php (100%) rename tests/{integration/assert-with-keys.phpt => feature/AssertWithKeys.php} (54%) create mode 100644 tests/feature/AssertWithProperties.php create mode 100644 tests/feature/AssertWithTemplates.php create mode 100644 tests/feature/DoNotRelyOnNestedValidationExceptionInterfaceForCheck.php create mode 100644 tests/feature/GetFullMessageShouldIncludeAllValidationMessagesInAChain.php create mode 100644 tests/feature/GetMessages.php create mode 100644 tests/feature/GetMessagesShouldIncludeAllValidationMessagesInAChain.php create mode 100644 tests/feature/GetMessagesWithReplacements.php create mode 100644 tests/feature/Issues/Issue1033Test.php create mode 100644 tests/feature/Issues/Issue1244Test.php rename tests/{integration/issues/1289.phpt => feature/Issues/Issue1289Test.php} (59%) create mode 100644 tests/feature/Issues/Issue1333Test.php create mode 100644 tests/feature/Issues/Issue1334Test.php create mode 100644 tests/feature/Issues/Issue1348Test.php create mode 100644 tests/feature/Issues/Issue1376Test.php create mode 100644 tests/feature/Issues/Issue1469Test.php create mode 100644 tests/feature/Issues/Issue1477Test.php create mode 100644 tests/feature/Issues/Issue179Test.php create mode 100644 tests/feature/Issues/Issue425Test.php create mode 100644 tests/feature/Issues/Issue446Test.php create mode 100644 tests/feature/Issues/Issue619Test.php create mode 100644 tests/feature/Issues/Issue739Test.php rename tests/{integration/issues/796.phpt => feature/Issues/Issue796Test.php} (56%) create mode 100644 tests/feature/Issues/Issue799Test.php create mode 100644 tests/feature/Issues/Issue805Test.php create mode 100644 tests/feature/KeysAsValidatorNames.php create mode 100644 tests/feature/NotWithRecursion.php create mode 100644 tests/feature/NotWithoutRecursion.php create mode 100644 tests/feature/Readme/CustomMessagesTest.php rename tests/{integration/readme/example_2.phpt => feature/Readme/ExampleTest.php} (58%) create mode 100644 tests/feature/Readme/GettingMessagesAsAnArrayTest.php create mode 100644 tests/feature/Rules/AllOfTest.php create mode 100644 tests/feature/Rules/AlnumTest.php create mode 100644 tests/feature/Rules/AlphaTest.php create mode 100644 tests/feature/Rules/AlwaysInvalidTest.php create mode 100644 tests/feature/Rules/AlwaysValidTest.php create mode 100644 tests/feature/Rules/ArrayTypeTest.php create mode 100644 tests/feature/Rules/ArrayValTest.php create mode 100644 tests/feature/Rules/AttributesTest.php create mode 100644 tests/feature/Rules/Base64Test.php create mode 100644 tests/feature/Rules/BaseTest.php create mode 100644 tests/feature/Rules/BeetwenTest.php create mode 100644 tests/feature/Rules/BetweenExclusiveTest.php create mode 100644 tests/feature/Rules/BoolTypeTest.php create mode 100644 tests/feature/Rules/BoolValTest.php create mode 100644 tests/feature/Rules/BsnTest.php create mode 100644 tests/feature/Rules/CallTest.php create mode 100644 tests/feature/Rules/CallableTypeTest.php create mode 100644 tests/feature/Rules/CallbackTest.php create mode 100644 tests/feature/Rules/CharsetTest.php create mode 100644 tests/feature/Rules/CnhTest.php create mode 100644 tests/feature/Rules/CnpjTest.php create mode 100644 tests/feature/Rules/CntrlTest.php create mode 100644 tests/feature/Rules/ConsecutiveTest.php create mode 100644 tests/feature/Rules/ConsonantTest.php create mode 100644 tests/feature/Rules/ContainsAnyTest.php create mode 100644 tests/feature/Rules/ContainsTest.php create mode 100644 tests/feature/Rules/CountableTest.php create mode 100644 tests/feature/Rules/CountryCodeTest.php create mode 100644 tests/feature/Rules/CpfTest.php create mode 100644 tests/feature/Rules/CreditCardTest.php create mode 100644 tests/feature/Rules/CurrencyCodeTest.php create mode 100644 tests/feature/Rules/DateTest.php create mode 100644 tests/feature/Rules/DateTimeDiffTest.php create mode 100644 tests/feature/Rules/DateTimeTest.php create mode 100644 tests/feature/Rules/DecimalTest.php create mode 100644 tests/feature/Rules/DigitTest.php create mode 100644 tests/feature/Rules/DirectoryTest.php create mode 100644 tests/feature/Rules/DomainTest.php create mode 100644 tests/feature/Rules/EachTest.php create mode 100644 tests/feature/Rules/EmailTest.php create mode 100644 tests/feature/Rules/EndsWithTest.php create mode 100644 tests/feature/Rules/EqualsTest.php create mode 100644 tests/feature/Rules/EquivalentTest.php create mode 100644 tests/feature/Rules/EvenTest.php create mode 100644 tests/feature/Rules/ExecutableTest.php create mode 100644 tests/feature/Rules/ExistsTest.php create mode 100644 tests/feature/Rules/ExtensionTest.php create mode 100644 tests/feature/Rules/FactorTest.php create mode 100644 tests/feature/Rules/FalseValTest.php create mode 100644 tests/feature/Rules/FibonacciTest.php create mode 100644 tests/feature/Rules/FileTest.php create mode 100644 tests/feature/Rules/FilterVarTest.php create mode 100644 tests/feature/Rules/FiniteTest.php create mode 100644 tests/feature/Rules/FloatTypeTest.php create mode 100644 tests/feature/Rules/FloatvalTest.php create mode 100644 tests/feature/Rules/GraphTest.php create mode 100644 tests/feature/Rules/GreaterThanOrEqualTest.php create mode 100644 tests/feature/Rules/GreaterThanTest.php create mode 100644 tests/feature/Rules/HetuTest.php create mode 100644 tests/feature/Rules/HexRgbColorTest.php create mode 100644 tests/feature/Rules/IbanTest.php create mode 100644 tests/feature/Rules/IdenticalTest.php create mode 100644 tests/feature/Rules/ImageTest.php create mode 100644 tests/feature/Rules/ImeiTest.php create mode 100644 tests/feature/Rules/InTest.php create mode 100644 tests/feature/Rules/InfiniteTest.php create mode 100644 tests/feature/Rules/InstanceTest.php create mode 100644 tests/feature/Rules/IntTypeTest.php create mode 100644 tests/feature/Rules/IntValTest.php create mode 100644 tests/feature/Rules/IpTest.php create mode 100644 tests/feature/Rules/IsbnTest.php create mode 100644 tests/feature/Rules/IterableTypeTest.php create mode 100644 tests/feature/Rules/IterableValTest.php create mode 100644 tests/feature/Rules/JsonTest.php create mode 100644 tests/feature/Rules/KeyExistsTest.php create mode 100644 tests/feature/Rules/KeyOptionalTest.php create mode 100644 tests/feature/Rules/KeySetTest.php create mode 100644 tests/feature/Rules/KeyTest.php create mode 100644 tests/feature/Rules/LanguageCodeTest.php create mode 100644 tests/feature/Rules/LazyTest.php create mode 100644 tests/feature/Rules/LeapDateTest.php create mode 100644 tests/feature/Rules/LeapYearTest.php create mode 100644 tests/feature/Rules/LengthTest.php create mode 100644 tests/feature/Rules/LessThanOrEqualTest.php create mode 100644 tests/feature/Rules/LessThanTest.php create mode 100644 tests/feature/Rules/LowercaseTest.php create mode 100644 tests/feature/Rules/LuhnTest.php create mode 100644 tests/feature/Rules/MacAddressTest.php create mode 100644 tests/feature/Rules/MaxTest.php create mode 100644 tests/feature/Rules/MimetypeTest.php create mode 100644 tests/feature/Rules/MinTest.php create mode 100644 tests/feature/Rules/MultipleTest.php create mode 100644 tests/feature/Rules/NegativeTest.php create mode 100644 tests/feature/Rules/NfeAccessKeyTest.php create mode 100644 tests/feature/Rules/NifTest.php create mode 100644 tests/feature/Rules/NipTest.php create mode 100644 tests/feature/Rules/NoTest.php create mode 100644 tests/feature/Rules/NoWhitespaceTest.php create mode 100644 tests/feature/Rules/NoneOfTest.php create mode 100644 tests/feature/Rules/NotBlankTest.php create mode 100644 tests/feature/Rules/NotEmojiTest.php create mode 100644 tests/feature/Rules/NotEmptyTest.php create mode 100644 tests/feature/Rules/NotUndefTest.php create mode 100644 tests/feature/Rules/NullOrTest.php create mode 100644 tests/feature/Rules/NullTypeTest.php create mode 100644 tests/feature/Rules/NumberTest.php create mode 100644 tests/feature/Rules/NumericValTest.php create mode 100644 tests/feature/Rules/ObjectTypeTest.php create mode 100644 tests/feature/Rules/OddTest.php create mode 100644 tests/feature/Rules/PerfectSquareTest.php create mode 100644 tests/feature/Rules/PeselTest.php create mode 100644 tests/feature/Rules/PhoneTest.php create mode 100644 tests/feature/Rules/PhplabelTest.php create mode 100644 tests/feature/Rules/PisTest.php create mode 100644 tests/feature/Rules/PolishIdCardTest.php create mode 100644 tests/feature/Rules/PositiveTest.php create mode 100644 tests/feature/Rules/PostalCodeTest.php create mode 100644 tests/feature/Rules/PrimeNumberTest.php create mode 100644 tests/feature/Rules/PrintableTest.php create mode 100644 tests/feature/Rules/PropertyExistsTest.php create mode 100644 tests/feature/Rules/PropertyOptionalTest.php create mode 100644 tests/feature/Rules/PropertyTest.php create mode 100644 tests/feature/Rules/PunctTest.php create mode 100644 tests/feature/Rules/ReadableTest.php create mode 100644 tests/feature/Rules/RegexTest.php create mode 100644 tests/feature/Rules/ResourceTypeTest.php create mode 100644 tests/feature/Rules/RomanTest.php create mode 100644 tests/feature/Rules/ScalarValTest.php create mode 100644 tests/feature/Rules/SizeTest.php create mode 100644 tests/feature/Rules/SlugTest.php create mode 100644 tests/feature/Rules/SortedTest.php create mode 100644 tests/feature/Rules/SpaceTest.php create mode 100644 tests/feature/Rules/StartsWithTest.php create mode 100644 tests/feature/Rules/StringTypeTest.php create mode 100644 tests/feature/Rules/StringValTest.php create mode 100644 tests/feature/Rules/SubsetTest.php create mode 100644 tests/feature/Rules/SymbolicLinkTest.php create mode 100644 tests/feature/Rules/TimeTest.php create mode 100644 tests/feature/Rules/TldTest.php create mode 100644 tests/feature/Rules/TrueValTest.php create mode 100644 tests/feature/Rules/UndefOrTest.php create mode 100644 tests/feature/Rules/UniqueTest.php create mode 100644 tests/feature/Rules/UploadedTest.php create mode 100644 tests/feature/Rules/UppercaseTest.php create mode 100644 tests/feature/Rules/UrlTest.php create mode 100644 tests/feature/Rules/UuidTest.php create mode 100644 tests/feature/Rules/VersionTest.php create mode 100644 tests/feature/Rules/VideoUrlTest.php create mode 100644 tests/feature/Rules/VowelTest.php create mode 100644 tests/feature/Rules/WhenTest.php create mode 100644 tests/feature/Rules/WritableTest.php create mode 100644 tests/feature/Rules/XdigitTest.php create mode 100644 tests/feature/Rules/YesTest.php create mode 100644 tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsFullMessage.php create mode 100644 tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsMainMessage.php create mode 100644 tests/feature/SetTemplateWithSingleValidatorShouldUseTemplateAsMainMessage.php create mode 100644 tests/feature/ShouldNotOverwriteDefinedNames.php create mode 100644 tests/feature/Transformers/AliasesTest.php create mode 100644 tests/feature/Transformers/DeprecatedAgeTest.php create mode 100644 tests/feature/Transformers/DeprecatedAttributeTest.php create mode 100644 tests/feature/Transformers/DeprecatedKeyNestedTest.php create mode 100644 tests/feature/Transformers/DeprecatedKeyTest.php create mode 100644 tests/feature/Transformers/DeprecatedKeyValueTest.php create mode 100644 tests/feature/Transformers/DeprecatedLengthTest.php create mode 100644 tests/feature/Transformers/DeprecatedMaxTest.php create mode 100644 tests/feature/Transformers/DeprecatedMinTest.php create mode 100644 tests/feature/Transformers/DeprecatedTypeTest.php create mode 100644 tests/feature/Transformers/PrefixTest.php rename tests/{integration/translator.phpt => feature/Translator.php} (59%) delete mode 100644 tests/integration/assert-with-properties.phpt delete mode 100644 tests/integration/assert-with-templates.phpt delete mode 100644 tests/integration/do_not_rely_on_nested_validation_exception_interface_for_check.phpt delete mode 100644 tests/integration/get_full_message_should_include_all_validation_messages_in_a_chain.phpt delete mode 100644 tests/integration/get_messages.phpt delete mode 100644 tests/integration/get_messages_should_include_all_validation_messages_in_a_chain.phpt delete mode 100644 tests/integration/get_messages_with_replacements.phpt delete mode 100644 tests/integration/issues/1033.phpt delete mode 100644 tests/integration/issues/1244.phpt delete mode 100644 tests/integration/issues/1333.phpt delete mode 100644 tests/integration/issues/1334.phpt delete mode 100644 tests/integration/issues/1348.phpt delete mode 100644 tests/integration/issues/1376.phpt delete mode 100644 tests/integration/issues/1469.phpt delete mode 100644 tests/integration/issues/1477.phpt delete mode 100644 tests/integration/issues/179.phpt delete mode 100644 tests/integration/issues/425.phpt delete mode 100644 tests/integration/issues/446.phpt delete mode 100644 tests/integration/issues/619.phpt delete mode 100644 tests/integration/issues/739.phpt delete mode 100644 tests/integration/issues/799.phpt delete mode 100644 tests/integration/issues/805.phpt delete mode 100644 tests/integration/keys_as_validator_names.phpt delete mode 100644 tests/integration/lib/helpers.php delete mode 100644 tests/integration/not_should_work_by_builder.phpt delete mode 100644 tests/integration/not_with_recursion.phpt delete mode 100644 tests/integration/not_without_recursion.phpt delete mode 100644 tests/integration/readme/custom_messages.phpt delete mode 100644 tests/integration/readme/example_1.phpt delete mode 100644 tests/integration/readme/getting_messages_as_an_array.phpt delete mode 100644 tests/integration/rules/allOf.phpt delete mode 100644 tests/integration/rules/alnum.phpt delete mode 100644 tests/integration/rules/alpha.phpt delete mode 100644 tests/integration/rules/alwaysInvalid.phpt delete mode 100644 tests/integration/rules/alwaysValid.phpt delete mode 100644 tests/integration/rules/arrayType.phpt delete mode 100644 tests/integration/rules/arrayVal.phpt delete mode 100644 tests/integration/rules/attributes.phpt delete mode 100644 tests/integration/rules/base.phpt delete mode 100644 tests/integration/rules/base64.phpt delete mode 100644 tests/integration/rules/beetwen.phpt delete mode 100644 tests/integration/rules/betweenExclusive.phpt delete mode 100644 tests/integration/rules/boolType.phpt delete mode 100644 tests/integration/rules/boolVal.phpt delete mode 100644 tests/integration/rules/bsn.phpt delete mode 100644 tests/integration/rules/call.phpt delete mode 100644 tests/integration/rules/callableType.phpt delete mode 100644 tests/integration/rules/callback.phpt delete mode 100644 tests/integration/rules/charset.phpt delete mode 100644 tests/integration/rules/cnh.phpt delete mode 100644 tests/integration/rules/cnpj.phpt delete mode 100644 tests/integration/rules/cntrl.phpt delete mode 100644 tests/integration/rules/consecutive.phpt delete mode 100644 tests/integration/rules/consonant.phpt delete mode 100644 tests/integration/rules/contains.phpt delete mode 100644 tests/integration/rules/containsAny.phpt delete mode 100644 tests/integration/rules/countable.phpt delete mode 100644 tests/integration/rules/countryCode.phpt delete mode 100644 tests/integration/rules/cpf.phpt delete mode 100644 tests/integration/rules/creditCard.phpt delete mode 100644 tests/integration/rules/currencyCode.phpt delete mode 100644 tests/integration/rules/date.phpt delete mode 100644 tests/integration/rules/dateTime.phpt delete mode 100644 tests/integration/rules/dateTimeDiff.phpt delete mode 100644 tests/integration/rules/decimal.phpt delete mode 100644 tests/integration/rules/digit.phpt delete mode 100644 tests/integration/rules/directory.phpt delete mode 100644 tests/integration/rules/domain.phpt delete mode 100644 tests/integration/rules/each.phpt delete mode 100644 tests/integration/rules/email.phpt delete mode 100644 tests/integration/rules/endsWith.phpt delete mode 100644 tests/integration/rules/equals.phpt delete mode 100644 tests/integration/rules/equivalent.phpt delete mode 100644 tests/integration/rules/even.phpt delete mode 100644 tests/integration/rules/executable.phpt delete mode 100644 tests/integration/rules/exists.phpt delete mode 100644 tests/integration/rules/extension.phpt delete mode 100644 tests/integration/rules/factor.phpt delete mode 100644 tests/integration/rules/falseVal.phpt delete mode 100644 tests/integration/rules/fibonacci.phpt delete mode 100644 tests/integration/rules/file.phpt delete mode 100644 tests/integration/rules/filterVar.phpt delete mode 100644 tests/integration/rules/finite.phpt delete mode 100644 tests/integration/rules/floatType.phpt delete mode 100644 tests/integration/rules/floatval.phpt delete mode 100644 tests/integration/rules/graph.phpt delete mode 100644 tests/integration/rules/greaterThan.phpt delete mode 100644 tests/integration/rules/greaterThanOrEqual.phpt delete mode 100644 tests/integration/rules/hetu.phpt delete mode 100644 tests/integration/rules/hexRgbColor.phpt delete mode 100644 tests/integration/rules/iban.phpt delete mode 100644 tests/integration/rules/identical.phpt delete mode 100644 tests/integration/rules/image.phpt delete mode 100644 tests/integration/rules/imei.phpt delete mode 100644 tests/integration/rules/in.phpt delete mode 100644 tests/integration/rules/infinite.phpt delete mode 100644 tests/integration/rules/instance.phpt delete mode 100644 tests/integration/rules/intType.phpt delete mode 100644 tests/integration/rules/intVal.phpt delete mode 100644 tests/integration/rules/ip.phpt delete mode 100644 tests/integration/rules/isbn.phpt delete mode 100644 tests/integration/rules/iterableType.phpt delete mode 100644 tests/integration/rules/iterableVal.phpt delete mode 100644 tests/integration/rules/json.phpt delete mode 100644 tests/integration/rules/key.phpt delete mode 100644 tests/integration/rules/keyExists.phpt delete mode 100644 tests/integration/rules/keyOptional.phpt delete mode 100644 tests/integration/rules/keySet.phpt delete mode 100644 tests/integration/rules/languageCode.phpt delete mode 100644 tests/integration/rules/lazy.phpt delete mode 100644 tests/integration/rules/leapDate.phpt delete mode 100644 tests/integration/rules/leapYear.phpt delete mode 100644 tests/integration/rules/length.phpt delete mode 100644 tests/integration/rules/lessThan.phpt delete mode 100644 tests/integration/rules/lessThanOrEqual.phpt delete mode 100644 tests/integration/rules/lowercase.phpt delete mode 100644 tests/integration/rules/luhn.phpt delete mode 100644 tests/integration/rules/macAddress.phpt delete mode 100644 tests/integration/rules/max.phpt delete mode 100644 tests/integration/rules/mimetype.phpt delete mode 100644 tests/integration/rules/min.phpt delete mode 100644 tests/integration/rules/multiple.phpt delete mode 100644 tests/integration/rules/negative.phpt delete mode 100644 tests/integration/rules/nfeAccessKey.phpt delete mode 100644 tests/integration/rules/nif.phpt delete mode 100644 tests/integration/rules/nip.phpt delete mode 100644 tests/integration/rules/no.phpt delete mode 100644 tests/integration/rules/noWhitespace.phpt delete mode 100644 tests/integration/rules/noneOf.phpt delete mode 100644 tests/integration/rules/notBlank.phpt delete mode 100644 tests/integration/rules/notEmoji.phpt delete mode 100644 tests/integration/rules/notEmpty.phpt delete mode 100644 tests/integration/rules/notUndef.phpt delete mode 100644 tests/integration/rules/nullOr.phpt delete mode 100644 tests/integration/rules/nullType.phpt delete mode 100644 tests/integration/rules/number.phpt delete mode 100644 tests/integration/rules/numericVal.phpt delete mode 100644 tests/integration/rules/objectType.phpt delete mode 100644 tests/integration/rules/odd.phpt delete mode 100644 tests/integration/rules/perfectSquare.phpt delete mode 100644 tests/integration/rules/pesel.phpt delete mode 100644 tests/integration/rules/phone.phpt delete mode 100644 tests/integration/rules/phplabel.phpt delete mode 100644 tests/integration/rules/pis.phpt delete mode 100644 tests/integration/rules/polishIdCard.phpt delete mode 100644 tests/integration/rules/positive.phpt delete mode 100644 tests/integration/rules/postalCode.phpt delete mode 100644 tests/integration/rules/primeNumber.phpt delete mode 100644 tests/integration/rules/printable.phpt delete mode 100644 tests/integration/rules/property.phpt delete mode 100644 tests/integration/rules/propertyExists.phpt delete mode 100644 tests/integration/rules/propertyOptional.phpt delete mode 100644 tests/integration/rules/punct.phpt delete mode 100644 tests/integration/rules/readable.phpt delete mode 100644 tests/integration/rules/regex.phpt delete mode 100644 tests/integration/rules/resourceType.phpt delete mode 100644 tests/integration/rules/roman.phpt delete mode 100644 tests/integration/rules/scalarVal.phpt delete mode 100644 tests/integration/rules/size.phpt delete mode 100644 tests/integration/rules/slug.phpt delete mode 100644 tests/integration/rules/sorted.phpt delete mode 100644 tests/integration/rules/space.phpt delete mode 100644 tests/integration/rules/startsWith.phpt delete mode 100644 tests/integration/rules/stringType.phpt delete mode 100644 tests/integration/rules/stringVal.phpt delete mode 100644 tests/integration/rules/subset.phpt delete mode 100644 tests/integration/rules/symbolicLink.phpt delete mode 100644 tests/integration/rules/time.phpt delete mode 100644 tests/integration/rules/tld.phpt delete mode 100644 tests/integration/rules/trueVal.phpt delete mode 100644 tests/integration/rules/undefOr.phpt delete mode 100644 tests/integration/rules/unique.phpt delete mode 100644 tests/integration/rules/uploaded.phpt delete mode 100644 tests/integration/rules/uppercase.phpt delete mode 100644 tests/integration/rules/url.phpt delete mode 100644 tests/integration/rules/uuid.phpt delete mode 100644 tests/integration/rules/version.phpt delete mode 100644 tests/integration/rules/videoUrl.phpt delete mode 100644 tests/integration/rules/vowel.phpt delete mode 100644 tests/integration/rules/when.phpt delete mode 100644 tests/integration/rules/writable.phpt delete mode 100644 tests/integration/rules/xdigit.phpt delete mode 100644 tests/integration/rules/yes.phpt delete mode 100644 tests/integration/set_template_with_multiple_validators_should_use_template_as_full_message.phpt delete mode 100644 tests/integration/set_template_with_multiple_validators_should_use_template_as_main_message.phpt delete mode 100644 tests/integration/set_template_with_single_validator_should_use_template_as_main_message.phpt delete mode 100644 tests/integration/should_not_overwrite_defined_names.phpt delete mode 100644 tests/integration/transformers/aliases.phpt delete mode 100644 tests/integration/transformers/deprecated_age.phpt delete mode 100644 tests/integration/transformers/deprecated_attribute.phpt delete mode 100644 tests/integration/transformers/deprecated_key.phpt delete mode 100644 tests/integration/transformers/deprecated_keyNested.phpt delete mode 100644 tests/integration/transformers/deprecated_keyValue.phpt delete mode 100644 tests/integration/transformers/deprecated_length.phpt delete mode 100644 tests/integration/transformers/deprecated_max.phpt delete mode 100644 tests/integration/transformers/deprecated_min.phpt delete mode 100644 tests/integration/transformers/deprecated_type.phpt delete mode 100644 tests/integration/transformers/prefix.phpt diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 7649e16e0..d09945a7d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -46,10 +46,10 @@ jobs: run: composer install --prefer-dist ${{ matrix.composer-extra-arguments }} - name: Run Unit Tests - run: ./vendor/phpunit/phpunit/phpunit --testsuite=unit + run: ./vendor/bin/phpunit --testsuite=unit - name: Run Integration Tests - run: ./vendor/phpunit/phpunit/phpunit --testsuite=integration + run: ./vendor/bin/pest --testsuite=feature --compact code-coverage: name: Code coverage @@ -78,7 +78,7 @@ jobs: run: composer install --prefer-dist ${{ matrix.composer-extra-arguments }} - name: Generating Code Coverage Report - run: ./vendor/phpunit/phpunit/phpunit --coverage-clover=coverage.xml + run: ./vendor/bin/pest --compact --coverage-clover=coverage.xml - name: Send Code Coverage Report to Codecov.io uses: codecov/codecov-action@v5 diff --git a/composer.json b/composer.json index 0fae6ab99..5a7f30faa 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "sort-packages": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, + "pestphp/pest-plugin": true, "phpstan/extension-installer": true } }, @@ -29,6 +30,7 @@ "malukenho/docheader": "^1.0", "mikey179/vfsstream": "^1.6", "nette/php-generator": "^4.1", + "pestphp/pest": "^2.36", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.0", "phpstan/phpstan-deprecation-rules": "^2.0", @@ -60,23 +62,20 @@ "Respect\\Validation\\": "tests/unit/", "Respect\\Validation\\Test\\": "tests/library/" }, - "files": [ - "tests/integration/lib/aliases.php", - "tests/integration/lib/helpers.php" - ] + "files": ["tests/aliases.php"] }, "scripts": { "docheader": "vendor/bin/docheader check library/ tests/", "phpcs": "vendor/bin/phpcs", "phpstan": "vendor/bin/phpstan analyze", - "phpunit": "vendor/bin/phpunit", - "phpunit-integration": "vendor/bin/phpunit --testsuite=integration", - "phpunit-unit": "vendor/bin/phpunit --testsuite=unit", + "phpunit": "vendor/bin/phpunit --testsuite=unit", + "pest": "vendor/bin/pest --testsuite=feature --compact", "qa": [ "@docheader", "@phpcs", "@phpstan", - "@phpunit" + "@phpunit", + "@pest" ] } } diff --git a/library/Transformers/DeprecatedAttribute.php b/library/Transformers/DeprecatedAttribute.php index aef8e819a..050880a6e 100644 --- a/library/Transformers/DeprecatedAttribute.php +++ b/library/Transformers/DeprecatedAttribute.php @@ -48,7 +48,7 @@ public function transform(RuleSpec $ruleSpec): RuleSpec if ($name === 'property') { trigger_error( - $firstMessage . ' Use property() without it.', + $firstMessage . ' Use property() instead.', E_USER_DEPRECATED ); } diff --git a/library/Transformers/DeprecatedKey.php b/library/Transformers/DeprecatedKey.php index 224178da9..e2c55e058 100644 --- a/library/Transformers/DeprecatedKey.php +++ b/library/Transformers/DeprecatedKey.php @@ -52,7 +52,7 @@ public function transform(RuleSpec $ruleSpec): RuleSpec if ($name === 'key') { trigger_error( 'Calling key() with a third parameter has been deprecated, ' . - 'and will be not be allowed in the next major version. Use key() without it the third parameter.', + 'and will be not be allowed in the next major version. Use key() without the third parameter.', E_USER_DEPRECATED ); } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 3257a8c0d..a913d82ce 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -16,7 +16,10 @@ - tests/integration/ + tests/feature/ + + + tests/Pest.php @@ -26,7 +29,4 @@ - - tests/integration/ - diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 603926219..43e2a2696 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,28 +7,32 @@ parameters: # Why: SimpleXMLElement is weird and doesn't implement anything ArrayAccess-like message: '/Instanceof between mixed and SimpleXMLElement will always evaluate to false\./' path: library/Rules/ArrayVal.php + - message: '/Call to an undefined method .+::skip\(\)/' + path: tests/feature + - message: '/Call to an undefined method .+::expectException\(\)/' + path: tests/Pest.php - message: '/Call to deprecated method optional\(\).+/' - path: tests/integration/transformers/aliases.phpt + path: tests/feature/Transformers/AliasesTest.php - message: '/Call to an undefined static method Respect\\Validation\\Validator::(min|max)Age\(\)./' - path: tests/integration/transformers/deprecated_age.phpt + path: tests/feature/Transformers/DeprecatedAgeTest.php - message: '/Call to an undefined static method Respect\\Validation\\Validator::attribute\(\)./' - path: tests/integration/transformers/deprecated_attribute.phpt + path: tests/feature/Transformers/DeprecatedAttributeTest.php - message: '/Static method Respect\\Validation\\Mixins\\StaticValidator::key\(\) invoked with \d parameters?, 2 required/' - path: tests/integration/transformers/deprecated_key.phpt + path: tests/feature/Transformers/DeprecatedKeyTest.php - message: '/Call to an undefined static method Respect\\Validation\\Validator::keyNested\(\)./' - path: tests/integration/transformers/deprecated_keyNested.phpt + path: tests/feature/Transformers/DeprecatedKeyNestedTest.php - message: '/Call to an undefined static method Respect\\Validation\\Validator::keyValue\(\)./' - path: tests/integration/transformers/deprecated_keyValue.phpt + path: tests/feature/Transformers/DeprecatedKeyValueTest.php - message: '/Parameter #1 \$rule of static method Respect\\Validation\\Mixins\\StaticValidator::length\(\) expects Respect\\Validation\\Rule.+/' - path: tests/integration/transformers/deprecated_length.phpt + path: tests/feature/Transformers/DeprecatedLengthTest.php - message: '/Static method Respect\\Validation\\Mixins\\StaticValidator::length\(\) invoked with \d parameters, 1 required/' - path: tests/integration/transformers/deprecated_length.phpt + path: tests/feature/Transformers/DeprecatedLengthTest.php - message: '/Parameter #1 \$rule of static method Respect\\Validation\\Mixins\\StaticValidator::max\(\) expects Respect\\Validation\\Rule.+/' - path: tests/integration/transformers/deprecated_max.phpt + path: tests/feature/Transformers/DeprecatedMaxTest.php - message: '/Parameter #1 \$rule of static method Respect\\Validation\\Mixins\\StaticValidator::min\(\) expects Respect\\Validation\\Rule.+/' - path: tests/integration/transformers/deprecated_min.phpt + path: tests/feature/Transformers/DeprecatedMinTest.php - message: '/Call to an undefined static method Respect\\Validation\\Validator::type\(\)./' - path: tests/integration/transformers/deprecated_type.phpt + path: tests/feature/Transformers/DeprecatedTypeTest.php - message: '/Method .+\\TestingStringifier::stringify\(\) never returns null so it can be removed from the return type./' path: tests/library/Message/TestingStringifier.php - message: '/Parameter #1 \$messages of class .+\\ArrayTranslator constructor expects array, array given./' diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 949e8c279..644ad9fbf 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,8 +11,8 @@ tests/unit/ - - tests/integration/ + + ./tests/feature diff --git a/tests/Pest.php b/tests/Pest.php new file mode 100644 index 000000000..dedefbdfc --- /dev/null +++ b/tests/Pest.php @@ -0,0 +1,101 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Exceptions\ValidationException; + +use function PHPUnit\Framework\assertStringMatchesFormat; + +/** @param array $messages */ +function expectAll(callable $callback, string $message, string $fullMessage, array $messages): Closure +{ + return function () use ($callback, $message, $fullMessage, $messages): void { + try { + $callback(); + test()->expectException(ValidationException::class); + } catch (ValidationException $e) { + expect($e->getMessage())->toBe($message) + ->and($e->getFullMessage())->toBe($fullMessage) + ->and($e->getMessages())->toBe($messages); + } + }; +} + +/** @param array $messages */ +function expectAllToMatch(callable $callback, string $message, string $fullMessage, array $messages): Closure +{ + return function () use ($callback, $message, $fullMessage, $messages): void { + try { + $callback(); + test()->expectException(ValidationException::class); + } catch (ValidationException $e) { + assertStringMatchesFormat($message, $e->getMessage(), 'Validation message does not match'); + assertStringMatchesFormat($fullMessage, $e->getFullMessage(), 'Validation full message does not match'); + foreach ($messages as $key => $value) { + assertStringMatchesFormat($value, $e->getMessages()[$key], 'Validation messages do not match'); + } + } + }; +} + +function expectMessage(callable $callback, string $message): Closure +{ + return function () use ($callback, $message): void { + try { + $callback(); + test()->expectException(ValidationException::class); + } catch (ValidationException $e) { + expect($e->getMessage())->toBe($message, 'Validation message does not match'); + } + }; +} + +function expectFullMessage(callable $callback, string $fullMessage): Closure +{ + return function () use ($callback, $fullMessage): void { + try { + $callback(); + test()->expectException(ValidationException::class); + } catch (ValidationException $exception) { + expect($exception->getFullMessage())->toBe($fullMessage, 'Validation full message does not match'); + } + }; +} + +/** @param array $messages */ +function expectMessages(callable $callback, array $messages): Closure +{ + return function () use ($callback, $messages): void { + try { + $callback(); + test()->expectException(ValidationException::class); + } catch (ValidationException $exception) { + expect($exception->getMessages())->toBe($messages, 'Validation messages do not match'); + } + }; +} + +function expectMessageAndError(Closure $callback, string $message, string $error): Closure +{ + return function () use ($callback, $message, $error): void { + $lastError = null; + set_error_handler(static function (int $errno, string $errstr) use (&$lastError): bool { + $lastError = $errstr; + + return true; + }); + try { + $callback(); + test()->expectException(ValidationException::class); + } catch (ValidationException $e) { + expect($e->getMessage())->toBe($message, 'Validation message does not match'); + } + restore_error_handler(); + expect($lastError)->toBe($error); + }; +} diff --git a/tests/integration/lib/aliases.php b/tests/aliases.php similarity index 100% rename from tests/integration/lib/aliases.php rename to tests/aliases.php diff --git a/tests/integration/assert-with-keys.phpt b/tests/feature/AssertWithKeys.php similarity index 54% rename from tests/integration/assert-with-keys.phpt rename to tests/feature/AssertWithKeys.php index 7b40f534d..6e8997b70 100644 --- a/tests/integration/assert-with-keys.phpt +++ b/tests/feature/AssertWithKeys.php @@ -1,10 +1,14 @@ ---FILE-- + * SPDX-License-Identifier: MIT + */ -exceptionFullMessage(static function (): void { - v::create() +declare(strict_types=1); + +test('Scenario #1', expectFullMessage( + static fn() => v::create() ->key( 'mysql', v::create() @@ -31,18 +35,18 @@ 'user' => 42, 'password' => 42, ], - ]); -}); -?> ---EXPECT-- -- All of the required rules must pass for the given data - - All of the required rules must pass for mysql - - host must be a string - - user must be present - - password must be present - - schema must be a string - - All of the required rules must pass for postgresql - - host must be present - - user must be a string - - password must be a string - - schema must be present \ No newline at end of file + ]), + <<<'MESSAGE' + - All of the required rules must pass for the given data + - All of the required rules must pass for mysql + - host must be a string + - user must be present + - password must be present + - schema must be a string + - All of the required rules must pass for postgresql + - host must be present + - user must be a string + - password must be a string + - schema must be present + MESSAGE, +)); diff --git a/tests/feature/AssertWithProperties.php b/tests/feature/AssertWithProperties.php new file mode 100644 index 000000000..297f4fdc2 --- /dev/null +++ b/tests/feature/AssertWithProperties.php @@ -0,0 +1,54 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectFullMessage( + static function (): void { + $array = [ + 'mysql' => [ + 'host' => 42, + 'user' => 'user', + 'password' => 'password', + 'schema' => 'schema', + ], + 'postgresql' => [ + 'host' => 'host', + 'user' => 42, + 'password' => 'password', + 'schema' => 'schema', + ], + ]; + $object = json_decode((string) json_encode($array)); + v::create() + ->property( + 'mysql', + v::create() + ->property('host', v::stringType()) + ->property('user', v::stringType()) + ->property('password', v::stringType()) + ->property('schema', v::stringType()) + ) + ->property( + 'postgresql', + v::create() + ->property('host', v::stringType()) + ->property('user', v::stringType()) + ->property('password', v::stringType()) + ->property('schema', v::stringType()) + ) + ->setName('the given data') + ->assert($object); + }, + <<<'MESSAGE' + - All of the required rules must pass for the given data + - These rules must pass for mysql + - host must be a string + - These rules must pass for postgresql + - user must be a string + MESSAGE, +)); diff --git a/tests/feature/AssertWithTemplates.php b/tests/feature/AssertWithTemplates.php new file mode 100644 index 000000000..7813deb75 --- /dev/null +++ b/tests/feature/AssertWithTemplates.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Template as a string in the chain', expectAll( + static fn() => v::alwaysInvalid()->assert(1, ['alwaysInvalid' => 'My runtime template an array']), + 'My string template in the chain', + '- My string template in the chain', + ['alwaysInvalid' => 'My string template in the chain',] +)); + +test('Template as an array in the chain', expectAll( + static fn() => v::alwaysInvalid()->assert(1, ['alwaysInvalid' => 'My runtime template an array']), + 'My array template in the chain', + '- My array template in the chain', + ['alwaysInvalid' => 'My array template in the chain',] +)); + +test('Runtime template as string', expectAll( + static fn() => v::alwaysInvalid()->assert(1, ['alwaysInvalid' => 'My runtime template an array']), + 'My runtime template as string', + '- My runtime template as string', + ['alwaysInvalid' => 'My runtime template as string',] +)); + +test('Runtime template as an array', expectAll( + static fn() => v::alwaysInvalid()->assert(1, ['alwaysInvalid' => 'My runtime template an array']), + 'My runtime template an array', + '- My runtime template an array', + ['alwaysInvalid' => 'My runtime template an array',] +)); diff --git a/tests/feature/DoNotRelyOnNestedValidationExceptionInterfaceForCheck.php b/tests/feature/DoNotRelyOnNestedValidationExceptionInterfaceForCheck.php new file mode 100644 index 000000000..c790f7a47 --- /dev/null +++ b/tests/feature/DoNotRelyOnNestedValidationExceptionInterfaceForCheck.php @@ -0,0 +1,15 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +test('Scenario #1', expectMessage( + static fn() => Validator::alnum('__')->lengthBetween(1, 15)->noWhitespace()->assert('really messed up screen#name'), + '"really messed up screen#name" must contain only letters (a-z), digits (0-9), and "__"', +)); diff --git a/tests/feature/GetFullMessageShouldIncludeAllValidationMessagesInAChain.php b/tests/feature/GetFullMessageShouldIncludeAllValidationMessagesInAChain.php new file mode 100644 index 000000000..c24850a60 --- /dev/null +++ b/tests/feature/GetFullMessageShouldIncludeAllValidationMessagesInAChain.php @@ -0,0 +1,19 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +test('Scenario #1', expectFullMessage( + static fn() => Validator::stringType()->lengthBetween(2, 15)->assert(0), + <<<'MESSAGE' + - All of the required rules must pass for 0 + - 0 must be a string + - The length of 0 must be between 2 and 15 + MESSAGE, +)); diff --git a/tests/feature/GetMessages.php b/tests/feature/GetMessages.php new file mode 100644 index 000000000..1a997a717 --- /dev/null +++ b/tests/feature/GetMessages.php @@ -0,0 +1,39 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessages( + static fn() => v::create() + ->key('mysql', v::create() + ->key('host', v::stringType()) + ->key('user', v::stringType())->key('password', v::stringType()) + ->key('schema', v::stringType())) + ->key('postgresql', v::create() + ->key('host', v::stringType()) + ->key('user', v::stringType()) + ->key('password', v::stringType()) + ->key('schema', v::stringType())) + ->assert(['mysql' => ['host' => 42, 'schema' => 42], 'postgresql' => ['user' => 42, 'password' => 42]]), + [ + '__root__' => 'All of the required rules must pass for `["mysql": ["host": 42, "schema": 42], "postgresql": ["user": 42, "password": 42]]`', + 'mysql' => [ + '__root__' => 'All of the required rules must pass for mysql', + 'host' => 'host must be a string', + 'user' => 'user must be present', + 'password' => 'password must be present', + 'schema' => 'schema must be a string', + ], + 'postgresql' => [ + '__root__' => 'All of the required rules must pass for postgresql', + 'host' => 'host must be present', + 'user' => 'user must be a string', + 'password' => 'password must be a string', + 'schema' => 'schema must be present', + ], + ], +)); diff --git a/tests/feature/GetMessagesShouldIncludeAllValidationMessagesInAChain.php b/tests/feature/GetMessagesShouldIncludeAllValidationMessagesInAChain.php new file mode 100644 index 000000000..0519a69fb --- /dev/null +++ b/tests/feature/GetMessagesShouldIncludeAllValidationMessagesInAChain.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + + +use Respect\Validation\Validator; + +test('Scenario #1', expectMessages( + static function (): void { + Validator::create() + ->key('username', Validator::lengthBetween(2, 32))->key('birthdate', Validator::dateTime()) + ->key('password', Validator::notEmpty()) + ->key('email', Validator::email()) + ->assert(['username' => 'u', 'birthdate' => 'Not a date', 'password' => '']); + }, + [ + '__root__' => 'All of the required rules must pass for `["username": "u", "birthdate": "Not a date", "password": ""]`', + 'username' => 'The length of username must be between 2 and 32', + 'birthdate' => 'birthdate must be a valid date/time', + 'password' => 'password must not be empty', + 'email' => 'email must be present', + ], +)); diff --git a/tests/feature/GetMessagesWithReplacements.php b/tests/feature/GetMessagesWithReplacements.php new file mode 100644 index 000000000..ad6cc71de --- /dev/null +++ b/tests/feature/GetMessagesWithReplacements.php @@ -0,0 +1,31 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessages( + static function (): void { + v::create()->key('mysql', v::create()->key('host', v::stringType())->key('user', v::stringType())->key('password', v::stringType())->key('schema', v::stringType()))->key('postgresql', v::create()->key('host', v::stringType())->key('user', v::stringType())->key('password', v::stringType())->key('schema', v::stringType()))->assert(['mysql' => ['host' => 42, 'schema' => 42], 'postgresql' => ['user' => 42, 'password' => 42]], ['mysql' => ['user' => 'Value should be a MySQL username', 'host' => '`{{name}}` should be a MySQL host'], 'postgresql' => ['schema' => 'You must provide a valid PostgreSQL schema']]); + }, + [ + '__root__' => 'All of the required rules must pass for `["mysql": ["host": 42, "schema": 42], "postgresql": ["user": 42, "password": 42]]`', + 'mysql' => [ + '__root__' => 'All of the required rules must pass for mysql', + 'host' => '`host` should be a MySQL host', + 'user' => 'Value should be a MySQL username', + 'password' => 'password must be present', + 'schema' => 'schema must be a string', + ], + 'postgresql' => [ + '__root__' => 'All of the required rules must pass for postgresql', + 'host' => 'host must be present', + 'user' => 'user must be a string', + 'password' => 'password must be a string', + 'schema' => 'You must provide a valid PostgreSQL schema', + ], + ], +)); diff --git a/tests/feature/Issues/Issue1033Test.php b/tests/feature/Issues/Issue1033Test.php new file mode 100644 index 000000000..05eb182bd --- /dev/null +++ b/tests/feature/Issues/Issue1033Test.php @@ -0,0 +1,25 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/1033', expectAll( + static fn() => v::each(v::equals(1))->assert(['A', 'B', 'B']), + '"A" must be equal to 1', + <<<'MESSAGE' + - Each item in `["A", "B", "B"]` must be valid + - "A" must be equal to 1 + - "B" must be equal to 1 + - "B" must be equal to 1 + MESSAGE, + [ + '__root__' => 'Each item in `["A", "B", "B"]` must be valid', + 'equals.1' => '"A" must be equal to 1', + 'equals.2' => '"B" must be equal to 1', + 'equals.3' => '"B" must be equal to 1', + ] +)); diff --git a/tests/feature/Issues/Issue1244Test.php b/tests/feature/Issues/Issue1244Test.php new file mode 100644 index 000000000..f1956d730 --- /dev/null +++ b/tests/feature/Issues/Issue1244Test.php @@ -0,0 +1,15 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/1244', expectAll( + static fn() => v::key('firstname', v::notBlank()->setName('First Name'))->assert([]), + 'First Name must be present', + '- First Name must be present', + ['firstname' => 'First Name must be present',] +)); diff --git a/tests/integration/issues/1289.phpt b/tests/feature/Issues/Issue1289Test.php similarity index 59% rename from tests/integration/issues/1289.phpt rename to tests/feature/Issues/Issue1289Test.php index d5341202c..afb800f03 100644 --- a/tests/integration/issues/1289.phpt +++ b/tests/feature/Issues/Issue1289Test.php @@ -1,6 +1,12 @@ ---FILE-- + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + use Respect\Validation\Rules\ArrayType; use Respect\Validation\Rules\BoolType; use Respect\Validation\Rules\Each; @@ -10,8 +16,6 @@ use Respect\Validation\Rules\StringVal; use Respect\Validation\Validator; -require 'vendor/autoload.php'; - $validator = Validator::create( new Each( Validator::create( @@ -41,25 +45,26 @@ 'children' => ['nope'], ], ]; -exceptionAll('https://github.com/Respect/Validation/issues/1289', static fn() => $validator->assert($input)); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1289 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -default must be a string + +test('https://github.com/Respect/Validation/issues/1289', expectAll( + static fn() => $validator->assert($input), + 'default must be a string', + <<<'MESSAGE' - These rules must pass for `["default": 2, "description": [], "children": ["nope"]]` - Only one of these rules must pass for default - default must be a string - default must be a boolean - description must be a string value -[ - 'allOf' => [ - '__root__' => 'These rules must pass for `["default": 2, "description": [], "children": ["nope"]]`', - 'default' => [ - '__root__' => 'Only one of these rules must pass for default', - 'stringType' => 'default must be a string', - 'boolType' => 'default must be a boolean', +MESSAGE, + [ + 'allOf' => [ + '__root__' => 'These rules must pass for `["default": 2, "description": [], "children": ["nope"]]`', + 'default' => [ + '__root__' => 'Only one of these rules must pass for default', + 'stringType' => 'default must be a string', + 'boolType' => 'default must be a boolean', + ], + 'description' => 'description must be a string value', ], - 'description' => 'description must be a string value', - ], -] + ] +)); diff --git a/tests/feature/Issues/Issue1333Test.php b/tests/feature/Issues/Issue1333Test.php new file mode 100644 index 000000000..bdaeb6afa --- /dev/null +++ b/tests/feature/Issues/Issue1333Test.php @@ -0,0 +1,23 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/1333', expectAll( + static fn() => v::noWhitespace()->email()->setName('User Email')->assert('not email'), + 'User Email must not contain whitespaces', + <<<'MESSAGE' +- All of the required rules must pass for User Email + - User Email must not contain whitespaces + - User Email must be a valid email address +MESSAGE, + [ + '__root__' => 'All of the required rules must pass for User Email', + 'noWhitespace' => 'User Email must not contain whitespaces', + 'email' => 'User Email must be a valid email address', + ] +)); diff --git a/tests/feature/Issues/Issue1334Test.php b/tests/feature/Issues/Issue1334Test.php new file mode 100644 index 000000000..c254b1d84 --- /dev/null +++ b/tests/feature/Issues/Issue1334Test.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/1334', expectAll( + static function (): void { + v::notEmpty()->iterableType()->each(v::key('street', v::stringType()->notEmpty())->key('region', v::stringType()->notEmpty())->key('country', v::stringType()->notEmpty())->keyOptional('other', v::nullOr(v::notEmpty()->stringType())))->assert([['region' => 'Oregon', 'country' => 'USA', 'other' => 123], ['street' => '', 'region' => 'Oregon', 'country' => 'USA'], ['street' => 123, 'region' => 'Oregon', 'country' => 'USA']]); + }, + 'street must be present', + <<<'MESSAGE' +- Each item in `[["region": "Oregon", "country": "USA", "other": 123], ["street": "", "region": "Oregon", "country": "USA"], ["s ... ]` must be valid + - These rules must pass for `["region": "Oregon", "country": "USA", "other": 123]` + - street must be present + - These rules must pass for other + - other must be a string or must be null + - These rules must pass for `["street": "", "region": "Oregon", "country": "USA"]` + - street must not be empty + - These rules must pass for `["street": 123, "region": "Oregon", "country": "USA"]` + - street must be a string +MESSAGE, + [ + 'each' => [ + '__root__' => 'Each item in `[["region": "Oregon", "country": "USA", "other": 123], ["street": "", "region": "Oregon", "country": "USA"], ["s ... ]` must be valid', + 'allOf.1' => [ + '__root__' => 'These rules must pass for `["region": "Oregon", "country": "USA", "other": 123]`', + 'street' => 'street must be present', + 'other' => 'other must be a string or must be null', + ], + 'allOf.2' => 'street must not be empty', + 'allOf.3' => 'street must be a string', + ], + ] +)); diff --git a/tests/feature/Issues/Issue1348Test.php b/tests/feature/Issues/Issue1348Test.php new file mode 100644 index 000000000..945149bf2 --- /dev/null +++ b/tests/feature/Issues/Issue1348Test.php @@ -0,0 +1,82 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +$cars = [ + ['manufacturer' => 'Honda', 'model' => 'Accord'], + ['manufacturer' => 'Toyota', 'model' => 'Rav4'], + ['manufacturer' => 'Ford', 'model' => 'not real'], + ['manufacturer' => 'Honda', 'model' => 'not valid'], +]; + +test('https://github.com/Respect/Validation/issues/1289', expectAll( + static fn() => v::arrayType()->each( + v::oneOf( + v::key('manufacturer', v::equals('Honda'))->key('model', v::in(['Accord', 'Fit'])), + v::key('manufacturer', v::equals('Toyota'))->key('model', v::in(['Rav4', 'Camry'])), + v::key('manufacturer', v::equals('Ford'))->key('model', Validator::in(['F150', 'Bronco'])) + ) + )->assert($cars), + 'manufacturer must be equal to "Honda"', + <<<'MESSAGE' + - Each item in `[["manufacturer": "Honda", "model": "Accord"], ["manufacturer": "Toyota", "model": "Rav4"], ["manufacturer": "Fo ... ]` must be valid + - Only one of these rules must pass for `["manufacturer": "Ford", "model": "not real"]` + - All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]` + - manufacturer must be equal to "Honda" + - model must be in `["Accord", "Fit"]` + - All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]` + - manufacturer must be equal to "Toyota" + - model must be in `["Rav4", "Camry"]` + - These rules must pass for `["manufacturer": "Ford", "model": "not real"]` + - model must be in `["F150", "Bronco"]` + - Only one of these rules must pass for `["manufacturer": "Honda", "model": "not valid"]` + - These rules must pass for `["manufacturer": "Honda", "model": "not valid"]` + - model must be in `["Accord", "Fit"]` + - All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]` + - manufacturer must be equal to "Toyota" + - model must be in `["Rav4", "Camry"]` + - All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]` + - manufacturer must be equal to "Ford" + - model must be in `["F150", "Bronco"]` + MESSAGE, + [ + 'each' => [ + '__root__' => 'Each item in `[["manufacturer": "Honda", "model": "Accord"], ["manufacturer": "Toyota", "model": "Rav4"], ["manufacturer": "Fo ... ]` must be valid', + 'oneOf.3' => [ + '__root__' => 'Only one of these rules must pass for `["manufacturer": "Ford", "model": "not real"]`', + 'allOf.1' => [ + '__root__' => 'All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]`', + 'manufacturer' => 'manufacturer must be equal to "Honda"', + 'model' => 'model must be in `["Accord", "Fit"]`', + ], + 'allOf.2' => [ + '__root__' => 'All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]`', + 'manufacturer' => 'manufacturer must be equal to "Toyota"', + 'model' => 'model must be in `["Rav4", "Camry"]`', + ], + 'allOf.3' => 'model must be in `["F150", "Bronco"]`', + ], + 'oneOf.4' => [ + '__root__' => 'Only one of these rules must pass for `["manufacturer": "Honda", "model": "not valid"]`', + 'allOf.1' => 'model must be in `["Accord", "Fit"]`', + 'allOf.2' => [ + '__root__' => 'All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]`', + 'manufacturer' => 'manufacturer must be equal to "Toyota"', + 'model' => 'model must be in `["Rav4", "Camry"]`', + ], + 'allOf.3' => [ + '__root__' => 'All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]`', + 'manufacturer' => 'manufacturer must be equal to "Ford"', + 'model' => 'model must be in `["F150", "Bronco"]`', + ], + ], + ], + ] +)); diff --git a/tests/feature/Issues/Issue1376Test.php b/tests/feature/Issues/Issue1376Test.php new file mode 100644 index 000000000..693b1740d --- /dev/null +++ b/tests/feature/Issues/Issue1376Test.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/1376', expectAll( + static fn() => v::create() + ->property('title', v::lengthBetween(2, 3)->stringType()) + ->property('description', v::stringType()) + ->property('author', v::intType()->lengthBetween(1, 2)) + ->property('user', v::intVal()->lengthBetween(1, 2)) + ->assert((object) ['author' => 'foo']), + 'title must be present', + <<<'MESSAGE' +- All of the required rules must pass for `stdClass { +$author="foo" }` + - title must be present + - description must be present + - All of the required rules must pass for author + - author must be an integer + - The length of author must be between 1 and 2 + - user must be present +MESSAGE, + [ + '__root__' => 'All of the required rules must pass for `stdClass { +$author="foo" }`', + 'title' => 'title must be present', + 'description' => 'description must be present', + 'author' => [ + '__root__' => 'All of the required rules must pass for author', + 'intType' => 'author must be an integer', + 'lengthBetween' => 'The length of author must be between 1 and 2', + ], + 'user' => 'user must be present', + ] +)); diff --git a/tests/feature/Issues/Issue1469Test.php b/tests/feature/Issues/Issue1469Test.php new file mode 100644 index 000000000..923f003cd --- /dev/null +++ b/tests/feature/Issues/Issue1469Test.php @@ -0,0 +1,37 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/1469', expectAll( + static function (): void { + $data = ['order_items' => [['product_title' => 'test', 'quantity' => 'test'], ['product_title2' => 'test']]]; + v::arrayVal()->keySet(v::key('order_items', v::arrayVal()->each(v::keySet(v::key('product_title', v::stringVal()->notEmpty()), v::key('quantity', v::intVal()->notEmpty())))->notEmpty()))->assert($data); + }, + 'quantity must be an integer value', + <<<'MESSAGE' +- Each item in order_items must be valid + - order_items validation failed + - quantity must be an integer value + - order_items contains both missing and extra keys + - product_title must be present + - quantity must be present + - product_title2 must not be present +MESSAGE, + [ + 'keySet' => [ + '__root__' => 'Each item in order_items must be valid', + 'keySet.1' => 'quantity must be an integer value', + 'keySet.2' => [ + '__root__' => 'order_items contains both missing and extra keys', + 'product_title' => 'product_title must be present', + 'quantity' => 'quantity must be present', + 'product_title2' => 'product_title2 must not be present', + ], + ], + ] +)); diff --git a/tests/feature/Issues/Issue1477Test.php b/tests/feature/Issues/Issue1477Test.php new file mode 100644 index 000000000..2a5e04a49 --- /dev/null +++ b/tests/feature/Issues/Issue1477Test.php @@ -0,0 +1,25 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Rules\Core\Simple; + +test('https://github.com/Respect/Validation/issues/1477', expectAll( + static function (): void { + v::key('Address', (new class extends Simple + { + protected function isValid(mixed $input): bool + { + return false; + } + })->setTemplate('{{name}} is not good!'))->assert(['Address' => 'cvejvn']); + }, + 'Address is not good!', + '- Address is not good!', + ['Address' => 'Address is not good!',] +)); diff --git a/tests/feature/Issues/Issue179Test.php b/tests/feature/Issues/Issue179Test.php new file mode 100644 index 000000000..9e7421b1f --- /dev/null +++ b/tests/feature/Issues/Issue179Test.php @@ -0,0 +1,37 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/179', expectAll( + static function (): void { + $config = [ + 'host' => 1, + 'password' => 'my_password', + 'schema' => 'my_schema', + ]; + + $validator = v::arrayType(); + $validator->setName('Settings'); + $validator->key('host', v::stringType()); + $validator->key('user', v::stringType()); + $validator->key('password', v::stringType()); + $validator->key('schema', v::stringType()); + $validator->assert($config); + }, + 'host must be a string', + <<<'MESSAGE' + - These rules must pass for Settings + - host must be a string + - user must be present + MESSAGE, + [ + '__root__' => 'These rules must pass for Settings', + 'host' => 'host must be a string', + 'user' => 'user must be present', + ] +)); diff --git a/tests/feature/Issues/Issue425Test.php b/tests/feature/Issues/Issue425Test.php new file mode 100644 index 000000000..7b9c15d28 --- /dev/null +++ b/tests/feature/Issues/Issue425Test.php @@ -0,0 +1,19 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$validator = v::create() + ->key('age', v::intType()->notEmpty()->noneOf(v::stringType(), v::arrayType())) + ->key('reference', v::stringType()->notEmpty()->lengthBetween(1, 50)); + +test('https://github.com/Respect/Validation/issues/425', expectAll( + static fn() => $validator->assert(['age' => 1]), + 'reference must be present', + '- reference must be present', + ['reference' => 'reference must be present',] +)); diff --git a/tests/feature/Issues/Issue446Test.php b/tests/feature/Issues/Issue446Test.php new file mode 100644 index 000000000..01a07b759 --- /dev/null +++ b/tests/feature/Issues/Issue446Test.php @@ -0,0 +1,23 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$arr = [ + 'name' => 'w', + 'email' => 'hello@hello.com', +]; + +test('https://github.com/Respect/Validation/issues/446', expectAll( + static fn() => v::create() + ->key('name', v::lengthBetween(2, 32)) + ->key('email', v::email()) + ->assert($arr), + 'The length of name must be between 2 and 32', + '- The length of name must be between 2 and 32', + ['name' => 'The length of name must be between 2 and 32',] +)); diff --git a/tests/feature/Issues/Issue619Test.php b/tests/feature/Issues/Issue619Test.php new file mode 100644 index 000000000..41b6da199 --- /dev/null +++ b/tests/feature/Issues/Issue619Test.php @@ -0,0 +1,15 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/619', expectAll( + static fn() => v::instance(stdClass::class)->setTemplate('invalid object')->assert('test'), + 'invalid object', + '- invalid object', + ['instance' => 'invalid object',] +)); diff --git a/tests/feature/Issues/Issue739Test.php b/tests/feature/Issues/Issue739Test.php new file mode 100644 index 000000000..c3bda135d --- /dev/null +++ b/tests/feature/Issues/Issue739Test.php @@ -0,0 +1,15 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/739', expectAll( + static fn() => v::when(v::alwaysInvalid(), v::alwaysValid())->assert('foo'), + '"foo" is invalid', + '- "foo" is invalid', + ['alwaysInvalid' => '"foo" is invalid',] +)); diff --git a/tests/integration/issues/796.phpt b/tests/feature/Issues/Issue796Test.php similarity index 56% rename from tests/integration/issues/796.phpt rename to tests/feature/Issues/Issue796Test.php index fd5bce7b2..1c905e304 100644 --- a/tests/integration/issues/796.phpt +++ b/tests/feature/Issues/Issue796Test.php @@ -1,10 +1,14 @@ ---FILE-- + * SPDX-License-Identifier: MIT + */ -exceptionAll('https://github.com/Respect/Validation/issues/796', static function (): void { - v::create() +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/796', expectAll( + static fn () => v::create() ->key( 'mysql', v::create() @@ -35,20 +39,18 @@ 'password' => 'password', 'schema' => 'schema', ], - ]); -}); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/796 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -host must be a string -- All of the required rules must pass for the given data - - These rules must pass for mysql - - host must be a string - - These rules must pass for postgresql - - user must be a string -[ - '__root__' => 'All of the required rules must pass for the given data', - 'mysql' => 'host must be a string', - 'postgresql' => 'user must be a string', -] + ]), + 'host must be a string', + <<<'MESSAGE' + - All of the required rules must pass for the given data + - These rules must pass for mysql + - host must be a string + - These rules must pass for postgresql + - user must be a string + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for the given data', + 'mysql' => 'host must be a string', + 'postgresql' => 'user must be a string', + ] +)); diff --git a/tests/feature/Issues/Issue799Test.php b/tests/feature/Issues/Issue799Test.php new file mode 100644 index 000000000..95948fc3b --- /dev/null +++ b/tests/feature/Issues/Issue799Test.php @@ -0,0 +1,46 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Test\Stubs\CountableStub; + +$input = 'http://www.google.com/search?q=respect.github.com'; + +test('https://github.com/Respect/Validation/issues/799 | #1', expectAll( + static fn() => v::create() + ->call( + [new CountableStub(1), 'count'], + v::arrayVal()->key('scheme', v::startsWith('https')) + ) + ->assert($input), + '1 must be an array value', + <<<'MESSAGE' + - All of the required rules must pass for 1 + - 1 must be an array value + - scheme must be present + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1', + 'arrayVal' => '1 must be an array value', + 'scheme' => 'scheme must be present', + ] +)); + +test('https://github.com/Respect/Validation/issues/799 | #2', expectAll( + static fn() => v::create() + ->call( + static function ($url) { + return parse_url($url); + }, + v::arrayVal()->key('scheme', v::startsWith('https')) + ) + ->assert($input), + 'scheme must start with "https"', + '- scheme must start with "https"', + ['scheme' => 'scheme must start with "https"',] +)); diff --git a/tests/feature/Issues/Issue805Test.php b/tests/feature/Issues/Issue805Test.php new file mode 100644 index 000000000..e2c62fbf9 --- /dev/null +++ b/tests/feature/Issues/Issue805Test.php @@ -0,0 +1,15 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('https://github.com/Respect/Validation/issues/805', expectAll( + static fn() => v::key('email', v::email()->setTemplate('WRONG EMAIL!!!!!!'))->assert(['email' => 'qwe']), + 'WRONG EMAIL!!!!!!', + '- WRONG EMAIL!!!!!!', + ['email' => 'WRONG EMAIL!!!!!!',] +)); diff --git a/tests/feature/KeysAsValidatorNames.php b/tests/feature/KeysAsValidatorNames.php new file mode 100644 index 000000000..8b6659c9f --- /dev/null +++ b/tests/feature/KeysAsValidatorNames.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + + +use Respect\Validation\Validator; + +test('Scenario #1', expectFullMessage( + static function (): void { + Validator::create() + ->key('username', Validator::length(Validator::between(2, 32))) + ->key('birthdate', Validator::dateTime()) + ->setName('User Subscription Form') + ->assert(['username' => '0', 'birthdate' => 'Whatever']); + }, + <<<'MESSAGE' + - All of the required rules must pass for User Subscription Form + - The length of username must be between 2 and 32 + - birthdate must be a valid date/time + MESSAGE, +)); diff --git a/tests/feature/NotWithRecursion.php b/tests/feature/NotWithRecursion.php new file mode 100644 index 000000000..a099d1955 --- /dev/null +++ b/tests/feature/NotWithRecursion.php @@ -0,0 +1,34 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$validator = v::not( + v::not( + v::not( + v::not( + v::not( + v::intVal()->positive() + ) + ) + ) + ) +); + +test('Scenario #1', expectMessage( + static fn() => $validator->assert(2), + '2 must not be an integer value', +)); + +test('Scenario #2', expectFullMessage( + static fn() => $validator->assert(2), + <<<'MESSAGE' +- These rules must not pass for 2 + - 2 must not be an integer value + - 2 must not be a positive number +MESSAGE, +)); diff --git a/tests/feature/NotWithoutRecursion.php b/tests/feature/NotWithoutRecursion.php new file mode 100644 index 000000000..537fb5c1e --- /dev/null +++ b/tests/feature/NotWithoutRecursion.php @@ -0,0 +1,18 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +test('Scenario #1', expectMessage( + static function (): void { + $validator = Validator::not(Validator::intVal()->positive()); + $validator->assert(2); + }, + '2 must not be an integer value', +)); diff --git a/tests/feature/Readme/CustomMessagesTest.php b/tests/feature/Readme/CustomMessagesTest.php new file mode 100644 index 000000000..1815c6a18 --- /dev/null +++ b/tests/feature/Readme/CustomMessagesTest.php @@ -0,0 +1,18 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessages( + static fn() => v::alnum()->noWhitespace()->length(v::between(1, 15))->assert('really messed up screen#name', ['alnum' => '{{name}} must contain only letters and digits', 'noWhitespace' => '{{name}} cannot contain spaces', 'length' => '{{name}} must not have more than 15 chars']), + [ + '__root__' => 'All of the required rules must pass for "really messed up screen#name"', + 'alnum' => '"really messed up screen#name" must contain only letters and digits', + 'noWhitespace' => '"really messed up screen#name" cannot contain spaces', + 'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15', + ], +)); diff --git a/tests/integration/readme/example_2.phpt b/tests/feature/Readme/ExampleTest.php similarity index 58% rename from tests/integration/readme/example_2.phpt rename to tests/feature/Readme/ExampleTest.php index 34ae6d913..8207750fc 100644 --- a/tests/integration/readme/example_2.phpt +++ b/tests/feature/Readme/ExampleTest.php @@ -1,14 +1,18 @@ ---FILE-- + * SPDX-License-Identifier: MIT + */ -exceptionFullMessage( - static fn() => v::alnum()->noWhitespace()->lengthBetween(1, 15)->assert('really messed up screen#name') -); -?> ---EXPECT-- +declare(strict_types=1); + +test('Scenario #1', expectFullMessage( + static fn() => v::alnum()->noWhitespace()->lengthBetween(1, 15)->assert('really messed up screen#name'), + <<<'MESSAGE' - All of the required rules must pass for "really messed up screen#name" - "really messed up screen#name" must contain only letters (a-z) and digits (0-9) - "really messed up screen#name" must not contain whitespaces - - The length of "really messed up screen#name" must be between 1 and 15 \ No newline at end of file + - The length of "really messed up screen#name" must be between 1 and 15 +MESSAGE, +)); diff --git a/tests/feature/Readme/GettingMessagesAsAnArrayTest.php b/tests/feature/Readme/GettingMessagesAsAnArrayTest.php new file mode 100644 index 000000000..723dcfbcb --- /dev/null +++ b/tests/feature/Readme/GettingMessagesAsAnArrayTest.php @@ -0,0 +1,18 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessages( + static fn() => v::alnum()->noWhitespace()->lengthBetween(1, 15)->assert('really messed up screen#name'), + [ + '__root__' => 'All of the required rules must pass for "really messed up screen#name"', + 'alnum' => '"really messed up screen#name" must contain only letters (a-z) and digits (0-9)', + 'noWhitespace' => '"really messed up screen#name" must not contain whitespaces', + 'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15', + ], +)); diff --git a/tests/feature/Rules/AllOfTest.php b/tests/feature/Rules/AllOfTest.php new file mode 100644 index 000000000..aefa131b2 --- /dev/null +++ b/tests/feature/Rules/AllOfTest.php @@ -0,0 +1,71 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Two rules', expectAll( + static fn() => v::allOf(v::intType(), v::negative())->assert('2'), + '"2" must be an integer', + <<<'MESSAGE' + - All of the required rules must pass for "2" + - "2" must be an integer + - "2" must be a negative number + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for "2"', + 'intType' => '"2" must be an integer', + 'negative' => '"2" must be a negative number', + ] +)); + +test('Wrapped by "not"', expectAll( + static fn() => v::not(v::allOf(v::intType(), v::positive()))->assert(3), + '3 must not be an integer', + <<<'MESSAGE' + - These rules must not pass for 3 + - 3 must not be an integer + - 3 must not be a positive number + MESSAGE, + [ + '__root__' => 'These rules must not pass for 3', + 'intType' => '3 must not be an integer', + 'positive' => '3 must not be a positive number', + ] +)); + +test('Wrapping "not"', expectAll( + static fn() => v::allOf(v::not(v::intType()), v::greaterThan(2))->assert(4), + '4 must not be an integer', + '- 4 must not be an integer', + ['notIntType' => '4 must not be an integer',] +)); + +test('With a single template', expectAll( + static fn() => v::allOf(v::stringType(), v::arrayType())->assert(5, 'This is a single template'), + 'This is a single template', + '- This is a single template', + ['allOf' => 'This is a single template',] +)); + +test('With multiple templates', expectAll( + static fn() => v::allOf(v::stringType(), v::uppercase())->assert(5, [ + '__root__' => 'Two things are wrong', + 'stringType' => 'Template for "stringType"', + 'uppercase' => 'Template for "uppercase"', + ]), + 'Template for "stringType"', + <<<'MESSAGE' + - Two things are wrong + - Template for "stringType" + - Template for "uppercase" + MESSAGE, + [ + '__root__' => 'Two things are wrong', + 'stringType' => 'Template for "stringType"', + 'uppercase' => 'Template for "uppercase"', + ] +)); diff --git a/tests/feature/Rules/AlnumTest.php b/tests/feature/Rules/AlnumTest.php new file mode 100644 index 000000000..b595d17f5 --- /dev/null +++ b/tests/feature/Rules/AlnumTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::alnum()->assert('abc%1'), + '"abc%1" must contain only letters (a-z) and digits (0-9)', +)); + +test('Scenario #2', expectMessage( + static fn() => v::alnum(' ')->assert('abc%2'), + '"abc%2" must contain only letters (a-z), digits (0-9), and " "', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::alnum())->assert('abcd3'), + '"abcd3" must not contain letters (a-z) or digits (0-9)', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::alnum('% '))->assert('abc%4'), + '"abc%4" must not contain letters (a-z), digits (0-9), or "% "', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::alnum()->assert('abc^1'), + '- "abc^1" must contain only letters (a-z) and digits (0-9)', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::alnum())->assert('abcd2'), + '- "abcd2" must not contain letters (a-z) or digits (0-9)', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::alnum('* &%')->assert('abc^3'), + '- "abc^3" must contain only letters (a-z), digits (0-9), and "* &%"', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::alnum('^'))->assert('abc^4'), + '- "abc^4" must not contain letters (a-z), digits (0-9), or "^"', +)); diff --git a/tests/feature/Rules/AlphaTest.php b/tests/feature/Rules/AlphaTest.php new file mode 100644 index 000000000..9e7f7eadf --- /dev/null +++ b/tests/feature/Rules/AlphaTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::alpha()->assert('aaa%a'), + '"aaa%a" must contain only letters (a-z)', +)); + +test('Scenario #2', expectMessage( + static fn() => v::alpha(' ')->assert('bbb%b'), + '"bbb%b" must contain only letters (a-z) and " "', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::alpha())->assert('ccccc'), + '"ccccc" must not contain letters (a-z)', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::alpha('% '))->assert('ddd%d'), + '"ddd%d" must not contain letters (a-z) or "% "', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::alpha()->assert('eee^e'), + '- "eee^e" must contain only letters (a-z)', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::alpha())->assert('fffff'), + '- "fffff" must not contain letters (a-z)', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::alpha('* &%')->assert('ggg^g'), + '- "ggg^g" must contain only letters (a-z) and "* &%"', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::alpha('^'))->assert('hhh^h'), + '- "hhh^h" must not contain letters (a-z) or "^"', +)); diff --git a/tests/feature/Rules/AlwaysInvalidTest.php b/tests/feature/Rules/AlwaysInvalidTest.php new file mode 100644 index 000000000..f826a10af --- /dev/null +++ b/tests/feature/Rules/AlwaysInvalidTest.php @@ -0,0 +1,18 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::alwaysInvalid()->assert('whatever'), + '"whatever" must be valid', +)); + +test('Scenario #2', expectFullMessage( + static fn() => v::alwaysInvalid()->assert(''), + '- "" must be valid', +)); diff --git a/tests/feature/Rules/AlwaysValidTest.php b/tests/feature/Rules/AlwaysValidTest.php new file mode 100644 index 000000000..1e918ae2d --- /dev/null +++ b/tests/feature/Rules/AlwaysValidTest.php @@ -0,0 +1,18 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::not(v::alwaysValid())->assert(true), + '`true` must be invalid', +)); + +test('Scenario #2', expectFullMessage( + static fn() => v::not(v::alwaysValid())->assert(true), + '- `true` must be invalid', +)); diff --git a/tests/feature/Rules/ArrayTypeTest.php b/tests/feature/Rules/ArrayTypeTest.php new file mode 100644 index 000000000..5a66e436d --- /dev/null +++ b/tests/feature/Rules/ArrayTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::arrayType()->assert('teste'), + '"teste" must be an array', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::arrayType())->assert([]), + '`[]` must not be an array', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::arrayType()->assert(new ArrayObject()), + '- `ArrayObject { getArrayCopy() => [] }` must be an array', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::arrayType())->assert([1, 2, 3]), + '- `[1, 2, 3]` must not be an array', +)); diff --git a/tests/feature/Rules/ArrayValTest.php b/tests/feature/Rules/ArrayValTest.php new file mode 100644 index 000000000..80080208b --- /dev/null +++ b/tests/feature/Rules/ArrayValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::arrayVal()->assert('Bla %123'), + '"Bla %123" must be an array value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::arrayVal())->assert([42]), + '`[42]` must not be an array value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::arrayVal()->assert(new stdClass()), + '- `stdClass {}` must be an array value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::arrayVal())->assert(new ArrayObject([2, 3])), + '- `ArrayObject { getArrayCopy() => [2, 3] }` must not be an array value', +)); diff --git a/tests/feature/Rules/AttributesTest.php b/tests/feature/Rules/AttributesTest.php new file mode 100644 index 000000000..ebc1fb517 --- /dev/null +++ b/tests/feature/Rules/AttributesTest.php @@ -0,0 +1,70 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Test\Stubs\WithAttributes; + +test('Default', expectAll( + static fn() => v::attributes()->assert(new WithAttributes('', 'john.doe@gmail.com', '2024-06-23')), + 'name must not be empty', + '- name must not be empty', + ['name' => 'name must not be empty',] +)); + +test('Inverted', expectAll( + static fn() => v::attributes()->assert(new WithAttributes('John Doe', 'john.doe@gmail.com', '2024-06-23', '+1234567890')), + 'phone must be a valid telephone number or must be null', + '- phone must be a valid telephone number or must be null', + ['phone' => 'phone must be a valid telephone number or must be null',] +)); + +test('Not an object', expectAll( + static fn() => v::attributes()->assert([]), + '`[]` must be an object', + '- `[]` must be an object', + ['attributes' => '`[]` must be an object',] +)); + +test('Nullable', expectAll( + static fn() => v::attributes()->assert(new WithAttributes('John Doe', 'john.doe@gmail.com', '2024-06-23', 'not a phone number')), + 'phone must be a valid telephone number or must be null', + '- phone must be a valid telephone number or must be null', + ['phone' => 'phone must be a valid telephone number or must be null',] +)); + +test('Multiple attributes, all failed', expectAll( + static fn() => v::attributes()->assert(new WithAttributes('', 'not an email', 'not a date', 'not a phone number')), + 'name must not be empty', + <<<'MESSAGE' + - All of the required rules must pass for `Respect\Validation\Test\Stubs\WithAttributes { +$name="" +$email="not an email" +$birthdate="not a date" +$phone ... }` + - name must not be empty + - email must be a valid email address + - All of the required rules must pass for birthdate + - birthdate must be a valid date in the format "2005-12-30" + - For comparison with now, birthdate must be a valid datetime + - phone must be a valid telephone number or must be null + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for `Respect\\Validation\\Test\\Stubs\\WithAttributes { +$name="" +$email="not an email" +$birthdate="not a date" +$phone ... }`', + 'name' => 'name must not be empty', + 'email' => 'email must be a valid email address', + 'birthdate' => [ + '__root__' => 'All of the required rules must pass for birthdate', + 'date' => 'birthdate must be a valid date in the format "2005-12-30"', + 'dateTimeDiffLessThanOrEqual' => 'For comparison with now, birthdate must be a valid datetime', + ], + 'phone' => 'phone must be a valid telephone number or must be null', + ] +)); + +test('Multiple attributes, one failed', expectAll( + static fn() => v::attributes()->assert(new WithAttributes('John Doe', 'john.doe@gmail.com', '22 years ago')), + 'birthdate must be a valid date in the format "2005-12-30"', + '- birthdate must be a valid date in the format "2005-12-30"', + ['birthdate' => 'birthdate must be a valid date in the format "2005-12-30"',] +)); diff --git a/tests/feature/Rules/Base64Test.php b/tests/feature/Rules/Base64Test.php new file mode 100644 index 000000000..8991253e2 --- /dev/null +++ b/tests/feature/Rules/Base64Test.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::base64()->assert('=c3VyZS4'), + '"=c3VyZS4" must be a base64 encoded string', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::base64())->assert('c3VyZS4='), + '"c3VyZS4=" must not be a base64 encoded string', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::base64()->assert('=c3VyZS4'), + '- "=c3VyZS4" must be a base64 encoded string', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::base64())->assert('c3VyZS4='), + '- "c3VyZS4=" must not be a base64 encoded string', +)); diff --git a/tests/feature/Rules/BaseTest.php b/tests/feature/Rules/BaseTest.php new file mode 100644 index 000000000..21c2d60cd --- /dev/null +++ b/tests/feature/Rules/BaseTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::base(61)->assert('Z01xSsg5675hic20dj'), + '"Z01xSsg5675hic20dj" must be a number in base 61', +)); + +test('Scenario #2', expectFullMessage( + static fn() => v::base(2)->assert(''), + '- "" must be a number in base 2', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::base(2))->assert('011010001'), + '"011010001" must not be a number in base 2', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::base(2))->assert('011010001'), + '- "011010001" must not be a number in base 2', +)); diff --git a/tests/feature/Rules/BeetwenTest.php b/tests/feature/Rules/BeetwenTest.php new file mode 100644 index 000000000..e16198fd0 --- /dev/null +++ b/tests/feature/Rules/BeetwenTest.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::between(1, 2)->assert(0), + '0 must be between 1 and 2', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::between('yesterday', 'tomorrow'))->assert('today'), + '"today" must not be between "yesterday" and "tomorrow"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::between('a', 'c')->assert('d'), + '- "d" must be between "a" and "c"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::between(-INF, INF))->assert(0), + '- 0 must not be between `-INF` and `INF`', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::not(v::between('a', 'b'))->assert('a'), + '- "a" must not be between "a" and "b"', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::between(1, 42))->assert(41), + '- 41 must not be between 1 and 42', +)); diff --git a/tests/feature/Rules/BetweenExclusiveTest.php b/tests/feature/Rules/BetweenExclusiveTest.php new file mode 100644 index 000000000..779a51527 --- /dev/null +++ b/tests/feature/Rules/BetweenExclusiveTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::betweenExclusive(1, 10)->assert(12), + '12 must be greater than 1 and less than 10', + '- 12 must be greater than 1 and less than 10', + ['betweenExclusive' => '12 must be greater than 1 and less than 10'] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::betweenExclusive(1, 10))->assert(5), + '5 must not be greater than 1 or less than 10', + '- 5 must not be greater than 1 or less than 10', + ['notBetweenExclusive' => '5 must not be greater than 1 or less than 10'] +)); + +test('With template', expectAll( + static fn() => v::betweenExclusive(1, 10)->setTemplate('Bewildered bees buzzed between blooming begonias')->assert(12), + 'Bewildered bees buzzed between blooming begonias', + '- Bewildered bees buzzed between blooming begonias', + ['betweenExclusive' => 'Bewildered bees buzzed between blooming begonias'] +)); + +test('With name', expectAll( + static fn() => v::betweenExclusive(1, 10)->setName('Range')->assert(10), + 'Range must be greater than 1 and less than 10', + '- Range must be greater than 1 and less than 10', + ['betweenExclusive' => 'Range must be greater than 1 and less than 10'] +)); diff --git a/tests/feature/Rules/BoolTypeTest.php b/tests/feature/Rules/BoolTypeTest.php new file mode 100644 index 000000000..7d04b59e0 --- /dev/null +++ b/tests/feature/Rules/BoolTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::boolType()->assert('teste'), + '"teste" must be a boolean', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::boolType())->assert(true), + '`true` must not be a boolean', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::boolType()->assert([]), + '- `[]` must be a boolean', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::boolType())->assert(false), + '- `false` must not be a boolean', +)); diff --git a/tests/feature/Rules/BoolValTest.php b/tests/feature/Rules/BoolValTest.php new file mode 100644 index 000000000..fdbc665a2 --- /dev/null +++ b/tests/feature/Rules/BoolValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::boolVal()->assert('ok'), + '"ok" must be a boolean value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::boolVal())->assert('yes'), + '"yes" must not be a boolean value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::boolVal()->assert('yep'), + '- "yep" must be a boolean value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::boolVal())->assert('on'), + '- "on" must not be a boolean value', +)); diff --git a/tests/feature/Rules/BsnTest.php b/tests/feature/Rules/BsnTest.php new file mode 100644 index 000000000..bcf05938a --- /dev/null +++ b/tests/feature/Rules/BsnTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::bsn()->assert('acb'), + '"acb" must be a valid BSN', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::bsn())->assert('612890053'), + '"612890053" must not be a valid BSN', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::bsn()->assert('abc'), + '- "abc" must be a valid BSN', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::bsn())->assert('612890053'), + '- "612890053" must not be a valid BSN', +)); diff --git a/tests/feature/Rules/CallTest.php b/tests/feature/Rules/CallTest.php new file mode 100644 index 000000000..0843dcf46 --- /dev/null +++ b/tests/feature/Rules/CallTest.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::call('trim', v::noWhitespace())->assert(' two words '), + '"two words" must not contain whitespaces', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::call('stripslashes', v::stringType()))->assert(' some\thing '), + '" something " must not be a string', +)); + +test('Scenario #3', expectMessage( + static fn() => v::call('stripslashes', v::alwaysValid())->assert([]), + '`[]` must be a suitable argument for `stripslashes(string $string): string`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::call('strval', v::intType())->assert(1234), + '- "1234" must be an integer', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::not(v::call('is_float', v::boolType()))->assert(1.2), + '- `true` must not be a boolean', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::call('array_shift', v::alwaysValid())->assert(INF), + '- `INF` must be a suitable argument for `array_shift(array &$array): ?mixed`', +)); diff --git a/tests/feature/Rules/CallableTypeTest.php b/tests/feature/Rules/CallableTypeTest.php new file mode 100644 index 000000000..9b16ea728 --- /dev/null +++ b/tests/feature/Rules/CallableTypeTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::callableType()->assert([]), + '`[]` must be a callable', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::callableType())->assert('trim'), + '`trim(string $string, string $characters = " \\n\\r\\t\\u000b\\u0000"): string` must not be a callable', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::callableType()->assert(true), + '- `true` must be a callable', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::callableType())->assert(static function (): void { + // Do nothing + }), + '- `function (): void` must not be a callable', +)); diff --git a/tests/feature/Rules/CallbackTest.php b/tests/feature/Rules/CallbackTest.php new file mode 100644 index 000000000..742438b2e --- /dev/null +++ b/tests/feature/Rules/CallbackTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::callback('is_string')->assert([]), + '`[]` must be valid', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::callback('is_string'))->assert('foo'), + '"foo" must be invalid', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::callback('is_string')->assert(true), + '- `true` must be valid', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::callback('is_string'))->assert('foo'), + '- "foo" must be invalid', +)); diff --git a/tests/feature/Rules/CharsetTest.php b/tests/feature/Rules/CharsetTest.php new file mode 100644 index 000000000..1c2ea19a4 --- /dev/null +++ b/tests/feature/Rules/CharsetTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::charset('ASCII')->assert('açaí'), + '"açaí" must only contain characters from the `["ASCII"]` charset', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::charset('UTF-8'))->assert('açaí'), + '"açaí" must not contain any characters from the `["UTF-8"]` charset', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::charset('ASCII')->assert('açaí'), + '- "açaí" must only contain characters from the `["ASCII"]` charset', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::charset('UTF-8'))->assert('açaí'), + '- "açaí" must not contain any characters from the `["UTF-8"]` charset', +)); diff --git a/tests/feature/Rules/CnhTest.php b/tests/feature/Rules/CnhTest.php new file mode 100644 index 000000000..f738bccd7 --- /dev/null +++ b/tests/feature/Rules/CnhTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::cnh()->assert('batman'), + '"batman" must be a valid CNH number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::cnh())->assert('02650306461'), + '"02650306461" must not be a valid CNH number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::cnh()->assert('bruce wayne'), + '- "bruce wayne" must be a valid CNH number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::cnh())->assert('02650306461'), + '- "02650306461" must not be a valid CNH number', +)); diff --git a/tests/feature/Rules/CnpjTest.php b/tests/feature/Rules/CnpjTest.php new file mode 100644 index 000000000..047685bd0 --- /dev/null +++ b/tests/feature/Rules/CnpjTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +require_once 'vendor/autoload.php'; + +test('Scenario #1', expectMessage( + static fn() => v::cnpj()->assert('não cnpj'), + '"não cnpj" must be a valid CNPJ number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::cnpj())->assert('65.150.175/0001-20'), + '"65.150.175/0001-20" must not be a valid CNPJ number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::cnpj()->assert('test'), + '- `test(?string $description = null, ?Closure $closure = null): Pest\\Support\\HigherOrderTapProxy|Pest\\PendingCalls\\Te ...` must be a valid CNPJ number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::cnpj())->assert('65.150.175/0001-20'), + '- "65.150.175/0001-20" must not be a valid CNPJ number', +)); diff --git a/tests/feature/Rules/CntrlTest.php b/tests/feature/Rules/CntrlTest.php new file mode 100644 index 000000000..ac853c4ce --- /dev/null +++ b/tests/feature/Rules/CntrlTest.php @@ -0,0 +1,50 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +require_once 'vendor/autoload.php'; + +test('Scenario #1', expectMessage( + static fn() => v::control()->assert('16-50'), + '"16-50" must only contain control characters', +)); + +test('Scenario #2', expectMessage( + static fn() => v::control('16')->assert('16-50'), + '"16-50" must only contain control characters and "16"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::control())->assert("\n"), + '"\\n" must not contain control characters', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::control('16'))->assert("16\n"), + '"16\\n" must not contain control characters or "16"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::control()->assert('Foo'), + '- "Foo" must only contain control characters', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::control('Bar')->assert('Foo'), + '- "Foo" must only contain control characters and "Bar"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::control())->assert("\n"), + '- "\\n" must not contain control characters', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::control('Bar'))->assert("Bar\n"), + '- "Bar\\n" must not contain control characters or "Bar"', +)); diff --git a/tests/feature/Rules/ConsecutiveTest.php b/tests/feature/Rules/ConsecutiveTest.php new file mode 100644 index 000000000..bb5767cf1 --- /dev/null +++ b/tests/feature/Rules/ConsecutiveTest.php @@ -0,0 +1,92 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::trueVal())->assert(false), + '`false` must evaluate to `true`', + '- `false` must evaluate to `true`', + ['trueVal' => '`false` must evaluate to `true`'] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::consecutive(v::alwaysValid(), v::trueVal()))->assert(true), + '`true` must not evaluate to `true`', + '- `true` must not evaluate to `true`', + ['notTrueVal' => '`true` must not evaluate to `true`'] +)); + +test('Default with inverted failing rule', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::not(v::trueVal()))->assert(true), + '`true` must not evaluate to `true`', + '- `true` must not evaluate to `true`', + ['notTrueVal' => '`true` must not evaluate to `true`'] +)); + +test('With wrapped name, default', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::trueVal()->setName('Wrapped'))->setName('Wrapper')->assert(false), + 'Wrapped must evaluate to `true`', + '- Wrapped must evaluate to `true`', + ['trueVal' => 'Wrapped must evaluate to `true`'] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::trueVal())->setName('Wrapper')->assert(false), + 'Wrapper must evaluate to `true`', + '- Wrapper must evaluate to `true`', + ['trueVal' => 'Wrapper must evaluate to `true`'] +)); + +test('With the name set in the wrapped rule of an inverted failing rule', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::not(v::trueVal()->setName('Wrapped'))->setName('Not'))->setName('Wrapper')->assert(true), + 'Wrapped must not evaluate to `true`', + '- Wrapped must not evaluate to `true`', + ['notTrueVal' => 'Wrapped must not evaluate to `true`'] +)); + +test('With the name set in an inverted failing rule', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::not(v::trueVal())->setName('Not'))->setName('Wrapper')->assert(true), + 'Not must not evaluate to `true`', + '- Not must not evaluate to `true`', + ['notTrueVal' => 'Not must not evaluate to `true`'] +)); + +test('With the name set in the "consecutive" that has an inverted failing rule', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::not(v::trueVal()))->setName('Wrapper')->assert(true), + 'Wrapper must not evaluate to `true`', + '- Wrapper must not evaluate to `true`', + ['notTrueVal' => 'Wrapper must not evaluate to `true`'] +)); + +test('With template', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::trueVal()) + ->setTemplate('Consecutive cool cats cunningly continuous cookies') + ->assert(false), + 'Consecutive cool cats cunningly continuous cookies', + '- Consecutive cool cats cunningly continuous cookies', + ['trueVal' => 'Consecutive cool cats cunningly continuous cookies'] +)); + +test('With multiple templates', expectAll( + static fn() => v::consecutive(v::alwaysValid(), v::trueVal()) + ->setTemplates(['trueVal' => 'Clever clowns craft consecutive clever clocks']) + ->assert(false), + 'Clever clowns craft consecutive clever clocks', + '- Clever clowns craft consecutive clever clocks', + ['trueVal' => 'Clever clowns craft consecutive clever clocks'] +)); + +test('Real example', expectAll( + static fn() => v::consecutive( + v::key('countyCode', v::countryCode()), + v::lazy(static fn($input) => v::key('subdivisionCode', v::subdivisionCode($input['countyCode']))) + )->assert(['countyCode' => 'BR', 'subdivisionCode' => 'CA']), + 'subdivisionCode must be a subdivision code of Brazil', + '- subdivisionCode must be a subdivision code of Brazil', + ['subdivisionCode' => 'subdivisionCode must be a subdivision code of Brazil'] +)); diff --git a/tests/feature/Rules/ConsonantTest.php b/tests/feature/Rules/ConsonantTest.php new file mode 100644 index 000000000..1bbeae5d5 --- /dev/null +++ b/tests/feature/Rules/ConsonantTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::consonant()->assert('aeiou'), + '"aeiou" must only contain consonants', +)); + +test('Scenario #2', expectMessage( + static fn() => v::consonant('d')->assert('daeiou'), + '"daeiou" must only contain consonants and "d"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::consonant())->assert('bcd'), + '"bcd" must not contain consonants', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::consonant('a'))->assert('abcd'), + '"abcd" must not contain consonants or "a"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::consonant()->assert('aeiou'), + '- "aeiou" must only contain consonants', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::consonant('d')->assert('daeiou'), + '- "daeiou" must only contain consonants and "d"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::consonant())->assert('bcd'), + '- "bcd" must not contain consonants', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::consonant('a'))->assert('abcd'), + '- "abcd" must not contain consonants or "a"', +)); diff --git a/tests/feature/Rules/ContainsAnyTest.php b/tests/feature/Rules/ContainsAnyTest.php new file mode 100644 index 000000000..f0afb08b1 --- /dev/null +++ b/tests/feature/Rules/ContainsAnyTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::containsAny(['foo', 'bar'])->assert('baz'), + '"baz" must contain at least one value from `["foo", "bar"]`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::containsAny(['foo', 'bar']))->assert('fool'), + '"fool" must not contain any value from `["foo", "bar"]`', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::containsAny(['foo', 'bar'])->assert(['baz']), + '- `["baz"]` must contain at least one value from `["foo", "bar"]`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::containsAny(['foo', 'bar'], true))->assert(['bar', 'foo']), + '- `["bar", "foo"]` must not contain any value from `["foo", "bar"]`', +)); diff --git a/tests/feature/Rules/ContainsTest.php b/tests/feature/Rules/ContainsTest.php new file mode 100644 index 000000000..1e059452a --- /dev/null +++ b/tests/feature/Rules/ContainsTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::contains('foo')->assert('bar'), + '"bar" must contain "foo"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::contains('foo'))->assert('fool'), + '"fool" must not contain "foo"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::contains('foo')->assert(['bar']), + '- `["bar"]` must contain "foo"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::contains('foo', true))->assert(['bar', 'foo']), + '- `["bar", "foo"]` must not contain "foo"', +)); diff --git a/tests/feature/Rules/CountableTest.php b/tests/feature/Rules/CountableTest.php new file mode 100644 index 000000000..3b2a2ad58 --- /dev/null +++ b/tests/feature/Rules/CountableTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::countable()->assert(1.0), + '1.0 must be a countable value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::countable())->assert([]), + '`[]` must not be a countable value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::countable()->assert('Not countable!'), + '- "Not countable!" must be a countable value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::countable())->assert(new ArrayObject()), + '- `ArrayObject { getArrayCopy() => [] }` must not be a countable value', +)); diff --git a/tests/feature/Rules/CountryCodeTest.php b/tests/feature/Rules/CountryCodeTest.php new file mode 100644 index 000000000..7cd6090b7 --- /dev/null +++ b/tests/feature/Rules/CountryCodeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::countryCode()->assert('1'), + '"1" must be a valid country code', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::countryCode())->assert('BR'), + '"BR" must not be a valid country code', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::countryCode()->assert('1'), + '- "1" must be a valid country code', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::countryCode())->assert('BR'), + '- "BR" must not be a valid country code', +)); diff --git a/tests/feature/Rules/CpfTest.php b/tests/feature/Rules/CpfTest.php new file mode 100644 index 000000000..9304871c3 --- /dev/null +++ b/tests/feature/Rules/CpfTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::cpf()->assert('this thing'), + '"this thing" must be a valid CPF number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::cpf())->assert('276.865.775-11'), + '"276.865.775-11" must not be a valid CPF number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::cpf()->assert('your mother'), + '- "your mother" must be a valid CPF number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::cpf())->assert('61836182848'), + '- "61836182848" must not be a valid CPF number', +)); diff --git a/tests/feature/Rules/CreditCardTest.php b/tests/feature/Rules/CreditCardTest.php new file mode 100644 index 000000000..070ff129e --- /dev/null +++ b/tests/feature/Rules/CreditCardTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::creditCard('Discover')->assert(3566002020360505), + '3566002020360505 must be a valid Discover credit card number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::creditCard('Visa'))->assert(4024007153361885), + '4024007153361885 must not be a valid Visa credit card number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::creditCard('MasterCard')->assert(3566002020360505), + '- 3566002020360505 must be a valid MasterCard credit card number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::creditCard())->assert(5555444433331111), + '- 5555444433331111 must not be a valid credit card number', +)); diff --git a/tests/feature/Rules/CurrencyCodeTest.php b/tests/feature/Rules/CurrencyCodeTest.php new file mode 100644 index 000000000..61769b862 --- /dev/null +++ b/tests/feature/Rules/CurrencyCodeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::currencyCode()->assert('batman'), + '"batman" must be a valid currency code', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::currencyCode())->assert('BRL'), + '"BRL" must not be a valid currency code', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::currencyCode()->assert('ppz'), + '- "ppz" must be a valid currency code', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::currencyCode())->assert('GBP'), + '- "GBP" must not be a valid currency code', +)); diff --git a/tests/feature/Rules/DateTest.php b/tests/feature/Rules/DateTest.php new file mode 100644 index 000000000..71a955612 --- /dev/null +++ b/tests/feature/Rules/DateTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + +test('Scenario #1', expectMessage( + static fn() => v::date()->assert('2018-01-29T08:32:54+00:00'), + '"2018-01-29T08:32:54+00:00" must be a valid date in the format "2005-12-30"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::date())->assert('2018-01-29'), + '"2018-01-29" must not be a valid date in the format "2005-12-30"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::date()->assert('2018-01-29T08:32:54+00:00'), + '- "2018-01-29T08:32:54+00:00" must be a valid date in the format "2005-12-30"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::date('d/m/Y'))->assert('29/01/2018'), + '- "29/01/2018" must not be a valid date in the format "30/12/2005"', +)); diff --git a/tests/feature/Rules/DateTimeDiffTest.php b/tests/feature/Rules/DateTimeDiffTest.php new file mode 100644 index 000000000..334b10005 --- /dev/null +++ b/tests/feature/Rules/DateTimeDiffTest.php @@ -0,0 +1,148 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('With $type = "years"', expectAll( + static fn() => v::dateTimeDiff('years', v::equals(2))->assert('1 year ago'), + 'The number of years between now and 1 year ago must be equal to 2', + '- The number of years between now and 1 year ago must be equal to 2', + ['dateTimeDiffEquals' => 'The number of years between now and 1 year ago must be equal to 2',] +)); + +test('With $type = "months"', expectAll( + static fn() => v::dateTimeDiff('months', v::equals(3))->assert('2 months ago'), + 'The number of months between now and 2 months ago must be equal to 3', + '- The number of months between now and 2 months ago must be equal to 3', + ['dateTimeDiffEquals' => 'The number of months between now and 2 months ago must be equal to 3',] +)); + +test('With $type = "days"', expectAll( + static fn() => v::dateTimeDiff('days', v::equals(4))->assert('3 days ago'), + 'The number of days between now and 3 days ago must be equal to 4', + '- The number of days between now and 3 days ago must be equal to 4', + ['dateTimeDiffEquals' => 'The number of days between now and 3 days ago must be equal to 4',] +)); + +test('With $type = "hours"', expectAll( + static fn() => v::dateTimeDiff('hours', v::equals(5))->assert('4 hours ago'), + 'The number of hours between now and 4 hours ago must be equal to 5', + '- The number of hours between now and 4 hours ago must be equal to 5', + ['dateTimeDiffEquals' => 'The number of hours between now and 4 hours ago must be equal to 5',] +)); + +test('With $type = "minutes"', expectAll( + static fn() => v::dateTimeDiff('minutes', v::equals(6))->assert('5 minutes ago'), + 'The number of minutes between now and 5 minutes ago must be equal to 6', + '- The number of minutes between now and 5 minutes ago must be equal to 6', + ['dateTimeDiffEquals' => 'The number of minutes between now and 5 minutes ago must be equal to 6',] +)); + +test('With $type = "microseconds"', expectAll( + static fn() => v::dateTimeDiff('microseconds', v::equals(7))->assert('6 microseconds ago'), + 'The number of microseconds between now and 6 microseconds ago must be equal to 7', + '- The number of microseconds between now and 6 microseconds ago must be equal to 7', + ['dateTimeDiffEquals' => 'The number of microseconds between now and 6 microseconds ago must be equal to 7',] +)); + +test('With custom $format', expectAllToMatch( + static fn() => v::dateTimeDiff('years', v::lessThan(8), 'd/m/Y')->assert('09/12/1988'), + 'The number of years between %d/%d/%d and 09/12/1988 must be less than 8', + '- The number of years between %d/%d/%d and 09/12/1988 must be less than 8', + ['dateTimeDiffLessThan' => 'The number of years between %d/%d/%d and 09/12/1988 must be less than 8',] +)); + +test('With input in non-parseable date', expectAll( + static fn() => v::dateTimeDiff('years', v::equals(2))->assert('not a date'), + 'For comparison with now, "not a date" must be a valid datetime', + '- For comparison with now, "not a date" must be a valid datetime', + ['dateTimeDiffEquals' => 'For comparison with now, "not a date" must be a valid datetime',] +)); + +test('With input in incorrect $format', expectAllToMatch( + static fn() => v::dateTimeDiff('years', v::equals(2), 'Y-m-d')->assert('1 year ago'), + 'For comparison with %d-%d-%d, "1 year ago" must be a valid datetime in the format %d-%d-%d', + '- For comparison with %d-%d-%d, "1 year ago" must be a valid datetime in the format %d-%d-%d', + ['dateTimeDiffEquals' => 'For comparison with %d-%d-%d, "1 year ago" must be a valid datetime in the format %d-%d-%d',] +)); + +test('With custom $now', expectAllToMatch( + static fn() => v::dateTimeDiff('years', v::lessThan(9), null, new DateTimeImmutable())->assert('09/12/1988'), + 'The number of years between %d-%d-%d %d:%d:%d.%d and 09/12/1988 must be less than 9', + '- The number of years between %d-%d-%d %d:%d:%d.%d and 09/12/1988 must be less than 9', + ['dateTimeDiffLessThan' => 'The number of years between %d-%d-%d %d:%d:%d.%d and 09/12/1988 must be less than 9',] +)); + +test('With custom template', expectAll( + static fn() => v::dateTimeDiff('years', v::equals(2)->setTemplate('Custom template'))->assert('1 year ago'), + 'Custom template', + '- Custom template', + ['equals' => 'Custom template',] +)); + +test('Wrapped by "not"', expectAll( + static fn() => v::not(v::dateTimeDiff('years', v::lessThan(8)))->assert('7 year ago'), + 'The number of years between now and 7 year ago must not be less than 8', + '- The number of years between now and 7 year ago must not be less than 8', + ['notDateTimeDiffLessThan' => 'The number of years between now and 7 year ago must not be less than 8',] +)); + +test('Wrapping "not"', expectAll( + static fn() => v::dateTimeDiff('years', v::not(v::lessThan(9)))->assert('8 year ago'), + 'The number of years between now and 8 year ago must not be less than 9', + '- The number of years between now and 8 year ago must not be less than 9', + ['dateTimeDiffNotLessThan' => 'The number of years between now and 8 year ago must not be less than 9',] +)); + +test('Wrapped with custom template', expectAll( + static fn() => v::dateTimeDiff('years', v::equals(2)->setTemplate('Wrapped with custom template'))->assert('1 year ago'), + 'Wrapped with custom template', + '- Wrapped with custom template', + ['equals' => 'Wrapped with custom template',] +)); + +test('Wrapper with custom template', expectAll( + static fn() => v::dateTimeDiff('years', v::equals(2))->setTemplate('Wrapper with custom template')->assert('1 year ago'), + 'Wrapper with custom template', + '- Wrapper with custom template', + ['dateTimeDiffEquals' => 'Wrapper with custom template',] +)); + +test('Without subsequent result', expectAll( + static fn() => v::dateTimeDiff('years', v::primeNumber()->between(2, 5))->assert('1 year ago'), + 'The number of years between now and 1 year ago must be a prime number', + <<<'MESSAGE' + - All of the required rules must pass for 1 year ago + - 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 between 2 and 5 + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1 year ago', + 'dateTimeDiffPrimeNumber' => 'The number of years between now and 1 year ago must be a prime number', + 'dateTimeDiffBetween' => 'The number of years between now and 1 year ago must be between 2 and 5', + ] +)); + +test('Without subsequent result with templates', expectAll( + static fn() => v::dateTimeDiff('years', v::primeNumber()->between(2, 5))->setTemplates([ + 'dateTimeDiff' => [ + 'primeNumber' => 'Interval must be a valid prime number', + 'between' => 'Interval must be between 2 and 5', + ], + ])->assert('1 year ago'), + 'The number of years between now and 1 year ago must be a prime number', + <<<'MESSAGE' + - All of the required rules must pass for 1 year ago + - 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 between 2 and 5 + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1 year ago', + 'dateTimeDiffPrimeNumber' => 'The number of years between now and 1 year ago must be a prime number', + 'dateTimeDiffBetween' => 'The number of years between now and 1 year ago must be between 2 and 5', + ] +)); diff --git a/tests/feature/Rules/DateTimeTest.php b/tests/feature/Rules/DateTimeTest.php new file mode 100644 index 000000000..c7c2de354 --- /dev/null +++ b/tests/feature/Rules/DateTimeTest.php @@ -0,0 +1,50 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + +test('Scenario #1', expectMessage( + static fn() => v::dateTime()->assert('FooBarBazz'), + '"FooBarBazz" must be a valid date/time', +)); + +test('Scenario #2', expectMessage( + static fn() => v::dateTime('c')->assert('06-12-1995'), + '"06-12-1995" must be a valid date/time in the format "2005-12-30T01:02:03+00:00"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::dateTime()->assert('QuxQuuxx'), + '- "QuxQuuxx" must be a valid date/time', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::dateTime('r')->assert(2018013030), + '- 2018013030 must be a valid date/time in the format "Fri, 30 Dec 2005 01:02:03 +0000"', +)); + +test('Scenario #5', expectMessage( + static fn() => v::not(v::dateTime())->assert('4 days ago'), + '"4 days ago" must not be a valid date/time', +)); + +test('Scenario #6', expectMessage( + static fn() => v::not(v::dateTime('Y-m-d'))->assert('1988-09-09'), + '"1988-09-09" must not be a valid date/time in the format "2005-12-30"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::dateTime())->assert('+3 weeks'), + '- "+3 weeks" must not be a valid date/time', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::dateTime('d/m/y'))->assert('23/07/99'), + '- "23/07/99" must not be a valid date/time in the format "30/12/05"', +)); diff --git a/tests/feature/Rules/DecimalTest.php b/tests/feature/Rules/DecimalTest.php new file mode 100644 index 000000000..e49de7ad0 --- /dev/null +++ b/tests/feature/Rules/DecimalTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::decimal(3)->assert(0.1234), + '0.1234 must have 3 decimals', +)); + +test('Scenario #2', expectFullMessage( + static fn() => v::decimal(2)->assert(0.123), + '- 0.123 must have 2 decimals', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::decimal(5))->assert(0.12345), + '0.12345 must not have 5 decimals', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::decimal(2))->assert(0.34), + '- 0.34 must not have 2 decimals', +)); diff --git a/tests/feature/Rules/DigitTest.php b/tests/feature/Rules/DigitTest.php new file mode 100644 index 000000000..42356ce01 --- /dev/null +++ b/tests/feature/Rules/DigitTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::digit()->assert('abc'), + '"abc" must contain only digits (0-9)', +)); + +test('Scenario #2', expectMessage( + static fn() => v::digit('-')->assert('a-b'), + '"a-b" must contain only digits (0-9) and "-"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::digit())->assert('123'), + '"123" must not contain digits (0-9)', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::digit('-'))->assert('1-3'), + '"1-3" must not contain digits (0-9) and "-"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::digit()->assert('abc'), + '- "abc" must contain only digits (0-9)', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::digit('-')->assert('a-b'), + '- "a-b" must contain only digits (0-9) and "-"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::digit())->assert('123'), + '- "123" must not contain digits (0-9)', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::digit('-'))->assert('1-3'), + '- "1-3" must not contain digits (0-9) and "-"', +)); diff --git a/tests/feature/Rules/DirectoryTest.php b/tests/feature/Rules/DirectoryTest.php new file mode 100644 index 000000000..b52f4e205 --- /dev/null +++ b/tests/feature/Rules/DirectoryTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::directory()->assert('batman'), + '"batman" must be a directory', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::directory())->assert(dirname('/etc/')), + '"/" must not be a directory', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::directory()->assert('ppz'), + '- "ppz" must be a directory', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::directory())->assert(dirname('/etc/')), + '- "/" must not be a directory', +)); diff --git a/tests/feature/Rules/DomainTest.php b/tests/feature/Rules/DomainTest.php new file mode 100644 index 000000000..767b1799b --- /dev/null +++ b/tests/feature/Rules/DomainTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::domain()->assert('batman'), + '"batman" must be a valid domain', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::domain())->assert('r--w.com'), + '"r--w.com" must not be a valid domain', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::domain()->assert('p-éz-.kk'), + '- "p-éz-.kk" must be a valid domain', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::domain())->assert('github.com'), + '- "github.com" must not be a valid domain', +)); diff --git a/tests/feature/Rules/EachTest.php b/tests/feature/Rules/EachTest.php new file mode 100644 index 000000000..92971efd9 --- /dev/null +++ b/tests/feature/Rules/EachTest.php @@ -0,0 +1,241 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Non-iterable', expectAll( + static fn() => v::each(v::intType())->assert(null), + '`null` must be iterable', + '- `null` must be iterable', + ['each' => '`null` must be iterable',] +)); + +test('Empty', expectAll( + static fn() => v::each(v::intType())->assert([]), + 'The value must not be empty', + '- The value must not be empty', + ['each' => 'The value must not be empty',] +)); + +test('Default', expectAll( + static fn() => v::each(v::intType())->assert(['a', 'b', 'c']), + '"a" must be an integer', + <<<'MESSAGE' + - Each item in `["a", "b", "c"]` must be valid + - "a" must be an integer + - "b" must be an integer + - "c" must be an integer + MESSAGE, + [ + '__root__' => 'Each item in `["a", "b", "c"]` must be valid', + 'intType.1' => '"a" must be an integer', + 'intType.2' => '"b" must be an integer', + 'intType.3' => '"c" must be an integer', + ] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::each(v::intType()))->assert([1, 2, 3]), + '1 must not be an integer', + <<<'MESSAGE' + - Each item in `[1, 2, 3]` must be invalid + - 1 must not be an integer + - 2 must not be an integer + - 3 must not be an integer + MESSAGE, + [ + '__root__' => 'Each item in `[1, 2, 3]` must be invalid', + 'intType.1' => '1 must not be an integer', + 'intType.2' => '2 must not be an integer', + 'intType.3' => '3 must not be an integer', + ] +)); + +test('With name, non-iterable', expectAll( + static fn() => v::each(v::intType()->setName('Wrapped'))->setName('Wrapper')->assert(null), + 'Wrapped must be iterable', + '- Wrapped must be iterable', + ['Wrapped' => 'Wrapped must be iterable',] +)); + +test('With name, empty', expectAll( + static fn() => v::each(v::intType()->setName('Wrapped'))->setName('Wrapper')->assert([]), + 'Wrapped must not be empty', + '- Wrapped must not be empty', + ['Wrapped' => 'Wrapped must not be empty',] +)); + +test('With name, default', expectAll( + static fn() => v::each(v::intType()->setName('Wrapped'))->setName('Wrapper')->assert(['a', 'b', 'c']), + 'Wrapped must be an integer', + <<<'MESSAGE' + - Each item in Wrapped must be valid + - Wrapped must be an integer + - Wrapped must be an integer + - Wrapped must be an integer + MESSAGE, + [ + '__root__' => 'Each item in Wrapped must be valid', + 'intType.1' => 'Wrapped must be an integer', + 'intType.2' => 'Wrapped must be an integer', + 'intType.3' => 'Wrapped must be an integer', + ] +)); + +test('With name, inverted', expectAll( + static fn() => v::not(v::each(v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not')->assert([1, 2, 3]), + 'Wrapped must not be an integer', + <<<'MESSAGE' + - Each item in Wrapped must be invalid + - Wrapped must not be an integer + - Wrapped must not be an integer + - Wrapped must not be an integer + MESSAGE, + [ + '__root__' => 'Each item in Wrapped must be invalid', + 'intType.1' => 'Wrapped must not be an integer', + 'intType.2' => 'Wrapped must not be an integer', + 'intType.3' => 'Wrapped must not be an integer', + ] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::each(v::intType())->setName('Wrapper')->assert(['a', 'b', 'c']), + 'Wrapper must be an integer', + <<<'MESSAGE' + - Each item in Wrapper must be valid + - Wrapper must be an integer + - Wrapper must be an integer + - Wrapper must be an integer + MESSAGE, + [ + '__root__' => 'Each item in Wrapper must be valid', + 'intType.1' => 'Wrapper must be an integer', + 'intType.2' => 'Wrapper must be an integer', + 'intType.3' => 'Wrapper must be an integer', + ] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::each(v::intType())->setName('Wrapper'))->setName('Not')->assert([1, 2, 3]), + 'Wrapper must not be an integer', + <<<'MESSAGE' + - Each item in Wrapper must be invalid + - Wrapper must not be an integer + - Wrapper must not be an integer + - Wrapper must not be an integer + MESSAGE, + [ + '__root__' => 'Each item in Wrapper must be invalid', + 'intType.1' => 'Wrapper must not be an integer', + 'intType.2' => 'Wrapper must not be an integer', + 'intType.3' => 'Wrapper must not be an integer', + ] +)); + +test('With Not name, inverted', expectAll( + static fn() => v::not(v::each(v::intType()))->setName('Not')->assert([1, 2, 3]), + 'Not must not be an integer', + <<<'MESSAGE' + - Each item in Not must be invalid + - Not must not be an integer + - Not must not be an integer + - Not must not be an integer + MESSAGE, + [ + '__root__' => 'Each item in Not must be invalid', + 'intType.1' => 'Not must not be an integer', + 'intType.2' => 'Not must not be an integer', + 'intType.3' => 'Not must not be an integer', + ] +)); + +test('With template, non-iterable', expectAll( + static fn() => v::each(v::intType())->setTemplate('You should have passed an iterable')->assert(null), + 'You should have passed an iterable', + '- You should have passed an iterable', + ['each' => 'You should have passed an iterable',] +)); + +test('With template, empty', expectAll( + static fn() => v::each(v::intType())->setTemplate('You should have passed an non-empty') + ->assert([]), + 'You should have passed an non-empty', + '- You should have passed an non-empty', + ['each' => 'You should have passed an non-empty',] +)); + +test('With template, default', expectAll( + static fn() => v::each(v::intType()) + ->setTemplate('All items should have been integers') + ->assert(['a', 'b', 'c']), + 'All items should have been integers', + '- All items should have been integers', + ['each' => 'All items should have been integers',] +)); + +test('with template, inverted', expectAll( + static fn() => v::not(v::each(v::intType())) + ->setTemplate('All items should not have been integers') + ->assert([1, 2, 3]), + 'All items should not have been integers', + '- All items should not have been integers', + ['notEach' => 'All items should not have been integers',] +)); + +test('With array template, default', expectAll( + static fn() => v::each(v::intType()) + ->setTemplates([ + 'each' => [ + '__root__' => 'Here a sequence of items that did not pass the validation', + 'intType.1' => 'First item should have been an integer', + 'intType.2' => 'Second item should have been an integer', + 'intType.3' => 'Third item should have been an integer', + ], + ]) + ->assert(['a', 'b', 'c']), + 'First item should have been an integer', + <<<'MESSAGE' + - Here a sequence of items that did not pass the validation + - First item should have been an integer + - Second item should have been an integer + - Third item should have been an integer + MESSAGE, + [ + '__root__' => 'Here a sequence of items that did not pass the validation', + 'intType.1' => 'First item should have been an integer', + 'intType.2' => 'Second item should have been an integer', + 'intType.3' => 'Third item should have been an integer', + ] +)); + +test('With array template and name, default', expectAll( + static fn() => v::each(v::intType()->setName('Wrapped')) + ->setName('Wrapper') + ->setTemplates([ + 'Wrapped' => [ + '__root__' => 'Here a sequence of items that did not pass the validation', + 'Wrapped.1' => 'First item should have been an integer', + 'Wrapped.2' => 'Second item should have been an integer', + 'Wrapped.3' => 'Third item should have been an integer', + ], + ]) + ->assert(['a', 'b', 'c']), + 'Wrapped must be an integer', + <<<'MESSAGE' + - Each item in Wrapped must be valid + - Wrapped must be an integer + - Wrapped must be an integer + - Wrapped must be an integer + MESSAGE, + [ + '__root__' => 'Each item in Wrapped must be valid', + 'intType.1' => 'Wrapped must be an integer', + 'intType.2' => 'Wrapped must be an integer', + 'intType.3' => 'Wrapped must be an integer', + ] +)); diff --git a/tests/feature/Rules/EmailTest.php b/tests/feature/Rules/EmailTest.php new file mode 100644 index 000000000..d13a5fade --- /dev/null +++ b/tests/feature/Rules/EmailTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::email()->assert('batman'), + '"batman" must be a valid email address', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::email())->assert('bruce.wayne@gothancity.com'), + '"bruce.wayne@gothancity.com" must not be an email address', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::email()->assert('bruce wayne'), + '- "bruce wayne" must be a valid email address', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::email())->assert('iambatman@gothancity.com'), + '- "iambatman@gothancity.com" must not be an email address', +)); diff --git a/tests/feature/Rules/EndsWithTest.php b/tests/feature/Rules/EndsWithTest.php new file mode 100644 index 000000000..8c3f363a1 --- /dev/null +++ b/tests/feature/Rules/EndsWithTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::endsWith('foo')->assert('bar'), + '"bar" must end with "foo"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::endsWith('foo'))->assert(['bar', 'foo']), + '`["bar", "foo"]` must not end with "foo"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::endsWith('foo')->assert(''), + '- "" must end with "foo"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::endsWith('foo'))->assert(['bar', 'foo']), + '- `["bar", "foo"]` must not end with "foo"', +)); diff --git a/tests/feature/Rules/EqualsTest.php b/tests/feature/Rules/EqualsTest.php new file mode 100644 index 000000000..6125beaa8 --- /dev/null +++ b/tests/feature/Rules/EqualsTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::equals(123)->assert(321), + '321 must be equal to 123', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::equals(321))->assert(321), + '321 must not be equal to 321', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::equals(123)->assert(321), + '- 321 must be equal to 123', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::equals(321))->assert(321), + '- 321 must not be equal to 321', +)); diff --git a/tests/feature/Rules/EquivalentTest.php b/tests/feature/Rules/EquivalentTest.php new file mode 100644 index 000000000..68ed9acae --- /dev/null +++ b/tests/feature/Rules/EquivalentTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::equivalent(true)->assert(false), + '`false` must be equivalent to `true`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::equivalent('Something'))->assert('someThing'), + '"someThing" must not be equivalent to "Something"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::equivalent(123)->assert('true'), + '- "true" must be equivalent to 123', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::equivalent(true))->assert(1), + '- 1 must not be equivalent to `true`', +)); diff --git a/tests/feature/Rules/EvenTest.php b/tests/feature/Rules/EvenTest.php new file mode 100644 index 000000000..ffdf63749 --- /dev/null +++ b/tests/feature/Rules/EvenTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::even()->assert(-1), + '-1 must be an even number', +)); + +test('Scenario #2', expectFullMessage( + static fn() => v::even()->assert(5), + '- 5 must be an even number', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::even())->assert(6), + '6 must be an odd number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::even())->assert(8), + '- 8 must be an odd number', +)); diff --git a/tests/feature/Rules/ExecutableTest.php b/tests/feature/Rules/ExecutableTest.php new file mode 100644 index 000000000..4d17c28b8 --- /dev/null +++ b/tests/feature/Rules/ExecutableTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::executable()->assert('bar'), + '"bar" must be an executable file', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::executable())->assert('tests/fixtures/executable'), + '"tests/fixtures/executable" must not be an executable file', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::executable()->assert('bar'), + '- "bar" must be an executable file', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::executable())->assert('tests/fixtures/executable'), + '- "tests/fixtures/executable" must not be an executable file', +)); diff --git a/tests/feature/Rules/ExistsTest.php b/tests/feature/Rules/ExistsTest.php new file mode 100644 index 000000000..ba3ebf486 --- /dev/null +++ b/tests/feature/Rules/ExistsTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::exists()->assert('/path/of/a/non-existent/file'), + '"/path/of/a/non-existent/file" must be an existing file', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::exists())->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must not be an existing file', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::exists()->assert('/path/of/a/non-existent/file'), + '- "/path/of/a/non-existent/file" must be an existing file', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::exists())->assert('tests/fixtures/valid-image.png'), + '- "tests/fixtures/valid-image.png" must not be an existing file', +)); diff --git a/tests/feature/Rules/ExtensionTest.php b/tests/feature/Rules/ExtensionTest.php new file mode 100644 index 000000000..097ed7bfe --- /dev/null +++ b/tests/feature/Rules/ExtensionTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::extension('png')->assert('filename.txt'), + '"filename.txt" must have "png" extension', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::extension('gif'))->assert('filename.gif'), + '"filename.gif" must not have "gif" extension', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::extension('mp3')->assert('filename.wav'), + '- "filename.wav" must have "mp3" extension', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::extension('png'))->assert('tests/fixtures/invalid-image.png'), + '- "tests/fixtures/invalid-image.png" must not have "png" extension', +)); diff --git a/tests/feature/Rules/FactorTest.php b/tests/feature/Rules/FactorTest.php new file mode 100644 index 000000000..5a43f002f --- /dev/null +++ b/tests/feature/Rules/FactorTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::factor(3)->assert(2), + '2 must be a factor of 3', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::factor(0))->assert(300), + '300 must not be a factor of 0', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::factor(5)->assert(3), + '- 3 must be a factor of 5', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::factor(6))->assert(1), + '- 1 must not be a factor of 6', +)); diff --git a/tests/feature/Rules/FalseValTest.php b/tests/feature/Rules/FalseValTest.php new file mode 100644 index 000000000..51115a3b1 --- /dev/null +++ b/tests/feature/Rules/FalseValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::falseVal()->assert(true), + '`true` must evaluate to `false`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::falseVal())->assert('false'), + '"false" must not evaluate to `false`', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::falseVal()->assert(1), + '- 1 must evaluate to `false`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::falseVal())->assert(0), + '- 0 must not evaluate to `false`', +)); diff --git a/tests/feature/Rules/FibonacciTest.php b/tests/feature/Rules/FibonacciTest.php new file mode 100644 index 000000000..c5ddabd63 --- /dev/null +++ b/tests/feature/Rules/FibonacciTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::fibonacci()->assert(4), + '4 must be a valid Fibonacci number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::fibonacci())->assert(5), + '5 must not be a valid Fibonacci number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::fibonacci()->assert(16), + '- 16 must be a valid Fibonacci number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::fibonacci())->assert(21), + '- 21 must not be a valid Fibonacci number', +)); diff --git a/tests/feature/Rules/FileTest.php b/tests/feature/Rules/FileTest.php new file mode 100644 index 000000000..a19219c26 --- /dev/null +++ b/tests/feature/Rules/FileTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::file()->assert('tests/fixtures/non-existent.sh'), + '"tests/fixtures/non-existent.sh" must be a valid file', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::file())->assert('tests/fixtures/valid-image.png'), + '"tests/fixtures/valid-image.png" must be an invalid file', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::file()->assert('tests/fixtures/non-existent.sh'), + '- "tests/fixtures/non-existent.sh" must be a valid file', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::file())->assert('tests/fixtures/valid-image.png'), + '- "tests/fixtures/valid-image.png" must be an invalid file', +)); diff --git a/tests/feature/Rules/FilterVarTest.php b/tests/feature/Rules/FilterVarTest.php new file mode 100644 index 000000000..59d6fc550 --- /dev/null +++ b/tests/feature/Rules/FilterVarTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::filterVar(FILTER_VALIDATE_IP)->assert(42), + '42 must be valid', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::filterVar(FILTER_VALIDATE_BOOLEAN))->assert('On'), + '"On" must not be valid', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::filterVar(FILTER_VALIDATE_EMAIL)->assert(1.5), + '- 1.5 must be valid', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::filterVar(FILTER_VALIDATE_FLOAT))->assert(1.0), + '- 1.0 must not be valid', +)); diff --git a/tests/feature/Rules/FiniteTest.php b/tests/feature/Rules/FiniteTest.php new file mode 100644 index 000000000..7e20a241e --- /dev/null +++ b/tests/feature/Rules/FiniteTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::finite()->assert(''), + '"" must be a finite number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::finite())->assert(10), + '10 must not be a finite number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::finite()->assert([12]), + '- `[12]` must be a finite number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::finite())->assert('123456'), + '- "123456" must not be a finite number', +)); diff --git a/tests/feature/Rules/FloatTypeTest.php b/tests/feature/Rules/FloatTypeTest.php new file mode 100644 index 000000000..b9bbd9459 --- /dev/null +++ b/tests/feature/Rules/FloatTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::floatType()->assert('42.33'), + '"42.33" must be float', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::floatType())->assert(INF), + '`INF` must not be float', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::floatType()->assert(true), + '- `true` must be float', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::floatType())->assert(2.0), + '- 2.0 must not be float', +)); diff --git a/tests/feature/Rules/FloatvalTest.php b/tests/feature/Rules/FloatvalTest.php new file mode 100644 index 000000000..67562e5a6 --- /dev/null +++ b/tests/feature/Rules/FloatvalTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::floatVal()->assert('a'), + '"a" must be a float value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::floatVal())->assert(165.0), + '165.0 must not be a float value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::floatVal()->assert('a'), + '- "a" must be a float value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::floatVal())->assert('165.7'), + '- "165.7" must not be a float value', +)); diff --git a/tests/feature/Rules/GraphTest.php b/tests/feature/Rules/GraphTest.php new file mode 100644 index 000000000..8632b1383 --- /dev/null +++ b/tests/feature/Rules/GraphTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::graph()->assert("foo\nbar"), + '"foo\\nbar" must contain only graphical characters', +)); + +test('Scenario #2', expectMessage( + static fn() => v::graph('foo')->assert("foo\nbar"), + '"foo\\nbar" must contain only graphical characters and "foo"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::graph())->assert('foobar'), + '"foobar" must not contain graphical characters', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::graph("\n"))->assert("foo\nbar"), + '"foo\\nbar" must not contain graphical characters or "\\n"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::graph()->assert("foo\nbar"), + '- "foo\\nbar" must contain only graphical characters', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::graph('foo')->assert("foo\nbar"), + '- "foo\\nbar" must contain only graphical characters and "foo"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::graph())->assert('foobar'), + '- "foobar" must not contain graphical characters', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::graph("\n"))->assert("foo\nbar"), + '- "foo\\nbar" must not contain graphical characters or "\\n"', +)); diff --git a/tests/feature/Rules/GreaterThanOrEqualTest.php b/tests/feature/Rules/GreaterThanOrEqualTest.php new file mode 100644 index 000000000..0a15e8df9 --- /dev/null +++ b/tests/feature/Rules/GreaterThanOrEqualTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::greaterThanOrEqual(INF)->assert(10), + '10 must be greater than or equal to `INF`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::greaterThanOrEqual(5))->assert(INF), + '`INF` must be less than 5', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::greaterThanOrEqual('today')->assert('yesterday'), + '- "yesterday" must be greater than or equal to "today"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::greaterThanOrEqual('a'))->assert('z'), + '- "z" must be less than "a"', +)); diff --git a/tests/feature/Rules/GreaterThanTest.php b/tests/feature/Rules/GreaterThanTest.php new file mode 100644 index 000000000..669fb491a --- /dev/null +++ b/tests/feature/Rules/GreaterThanTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::greaterThan(21)->assert(12), + '12 must be greater than 21', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::greaterThan('yesterday'))->assert('today'), + '"today" must not be greater than "yesterday"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::greaterThan('2018-09-09')->assert('1988-09-09'), + '- "1988-09-09" must be greater than "2018-09-09"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::greaterThan('a'))->assert('ba'), + '- "ba" must not be greater than "a"', +)); diff --git a/tests/feature/Rules/HetuTest.php b/tests/feature/Rules/HetuTest.php new file mode 100644 index 000000000..e483a64f0 --- /dev/null +++ b/tests/feature/Rules/HetuTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::hetu()->assert('010106A901O'), + '"010106A901O" must be a valid Finnish personal identity code', + '- "010106A901O" must be a valid Finnish personal identity code', + ['hetu' => '"010106A901O" must be a valid Finnish personal identity code',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::hetu())->assert('010106A9012'), + '"010106A9012" must not be a valid Finnish personal identity code', + '- "010106A9012" must not be a valid Finnish personal identity code', + ['notHetu' => '"010106A9012" must not be a valid Finnish personal identity code',] +)); + +test('With template', expectAll( + static fn() => v::hetu()->assert('010106A901O', 'That is not a HETU'), + 'That is not a HETU', + '- That is not a HETU', + ['hetu' => 'That is not a HETU',] +)); + +test('With name', expectAll( + static fn() => v::hetu()->setName('Hetu')->assert('010106A901O'), + 'Hetu must be a valid Finnish personal identity code', + '- Hetu must be a valid Finnish personal identity code', + ['hetu' => 'Hetu must be a valid Finnish personal identity code',] +)); diff --git a/tests/feature/Rules/HexRgbColorTest.php b/tests/feature/Rules/HexRgbColorTest.php new file mode 100644 index 000000000..12ec2a630 --- /dev/null +++ b/tests/feature/Rules/HexRgbColorTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::hexRgbColor()->assert('invalid'), + '"invalid" must be a hex RGB color', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::hexRgbColor())->assert('#808080'), + '"#808080" must not be a hex RGB color', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::hexRgbColor()->assert('invalid'), + '- "invalid" must be a hex RGB color', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::hexRgbColor())->assert('#808080'), + '- "#808080" must not be a hex RGB color', +)); diff --git a/tests/feature/Rules/IbanTest.php b/tests/feature/Rules/IbanTest.php new file mode 100644 index 000000000..9d5811863 --- /dev/null +++ b/tests/feature/Rules/IbanTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::iban()->assert('SE35 5000 5880 7742'), + '"SE35 5000 5880 7742" must be a valid IBAN', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::iban())->assert('GB82 WEST 1234 5698 7654 32'), + '"GB82 WEST 1234 5698 7654 32" must not be a valid IBAN', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::iban()->assert('NOT AN IBAN'), + '- "NOT AN IBAN" must be a valid IBAN', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::iban())->assert('HU93 1160 0006 0000 0000 1234 5676'), + '- "HU93 1160 0006 0000 0000 1234 5676" must not be a valid IBAN', +)); diff --git a/tests/feature/Rules/IdenticalTest.php b/tests/feature/Rules/IdenticalTest.php new file mode 100644 index 000000000..5bde082ca --- /dev/null +++ b/tests/feature/Rules/IdenticalTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::identical(123)->assert(321), + '321 must be identical to 123', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::identical(321))->assert(321), + '321 must not be identical to 321', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::identical(123)->assert(321), + '- 321 must be identical to 123', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::identical(321))->assert(321), + '- 321 must not be identical to 321', +)); diff --git a/tests/feature/Rules/ImageTest.php b/tests/feature/Rules/ImageTest.php new file mode 100644 index 000000000..94a9349d5 --- /dev/null +++ b/tests/feature/Rules/ImageTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::image()->assert('tests/fixtures/invalid-image.png'), + '"tests/fixtures/invalid-image.png" must be a valid image file', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::image())->assert('tests/fixtures/valid-image.png'), + '"tests/fixtures/valid-image.png" must not be a valid image file', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::image()->assert(new stdClass()), + '- `stdClass {}` must be a valid image file', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::image())->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must not be a valid image file', +)); diff --git a/tests/feature/Rules/ImeiTest.php b/tests/feature/Rules/ImeiTest.php new file mode 100644 index 000000000..99ec02279 --- /dev/null +++ b/tests/feature/Rules/ImeiTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::imei()->assert('490154203237512'), + '"490154203237512" must be a valid IMEI number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::imei())->assert('350077523237513'), + '"350077523237513" must not be a valid IMEI number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::imei()->assert(null), + '- `null` must be a valid IMEI number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::imei())->assert('356938035643809'), + '- "356938035643809" must not be a valid IMEI number', +)); diff --git a/tests/feature/Rules/InTest.php b/tests/feature/Rules/InTest.php new file mode 100644 index 000000000..085d0a8a3 --- /dev/null +++ b/tests/feature/Rules/InTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::in([3, 2])->assert(1), + '1 must be in `[3, 2]`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::in('foobar'))->assert('foo'), + '"foo" must not be in "foobar"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::in([2, '1', 3], true)->assert('2'), + '- "2" must be in `[2, "1", 3]`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::in([2, '1', 3], true))->assert('1'), + '- "1" must not be in `[2, "1", 3]`', +)); diff --git a/tests/feature/Rules/InfiniteTest.php b/tests/feature/Rules/InfiniteTest.php new file mode 100644 index 000000000..b9a41d176 --- /dev/null +++ b/tests/feature/Rules/InfiniteTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::infinite()->assert(-9), + '-9 must be an infinite number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::infinite())->assert(INF), + '`INF` must not be an infinite number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::infinite()->assert(new stdClass()), + '- `stdClass {}` must be an infinite number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::infinite())->assert(INF * -1), + '- `-INF` must not be an infinite number', +)); diff --git a/tests/feature/Rules/InstanceTest.php b/tests/feature/Rules/InstanceTest.php new file mode 100644 index 000000000..4a2ed2832 --- /dev/null +++ b/tests/feature/Rules/InstanceTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::instance(DateTime::class)->assert(''), + '"" must be an instance of `DateTime`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::instance(Traversable::class))->assert(new ArrayObject()), + '`ArrayObject { getArrayCopy() => [] }` must not be an instance of `Traversable`', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::instance(ArrayIterator::class)->assert(new stdClass()), + '- `stdClass {}` must be an instance of `ArrayIterator`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::instance(stdClass::class))->assert(new stdClass()), + '- `stdClass {}` must not be an instance of `stdClass`', +)); diff --git a/tests/feature/Rules/IntTypeTest.php b/tests/feature/Rules/IntTypeTest.php new file mode 100644 index 000000000..12d303472 --- /dev/null +++ b/tests/feature/Rules/IntTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::intType()->assert(new stdClass()), + '`stdClass {}` must be an integer', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::intType())->assert(42), + '42 must not be an integer', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::intType()->assert(INF), + '- `INF` must be an integer', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::intType())->assert(1234567890), + '- 1234567890 must not be an integer', +)); diff --git a/tests/feature/Rules/IntValTest.php b/tests/feature/Rules/IntValTest.php new file mode 100644 index 000000000..46dd7f88e --- /dev/null +++ b/tests/feature/Rules/IntValTest.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::intVal()->assert('42.33'), + '"42.33" must be an integer value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::intVal())->assert(2), + '2 must not be an integer value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::intVal()->assert('Foo'), + '- "Foo" must be an integer value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::intVal())->assert(3), + '- 3 must not be an integer value', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::not(v::intVal())->assert(-42), + '- -42 must not be an integer value', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::intVal())->assert('-42'), + '- "-42" must not be an integer value', +)); diff --git a/tests/feature/Rules/IpTest.php b/tests/feature/Rules/IpTest.php new file mode 100644 index 000000000..6899bd8b2 --- /dev/null +++ b/tests/feature/Rules/IpTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::ip()->assert('257.0.0.1'), + '"257.0.0.1" must be an IP address', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::ip())->assert('127.0.0.1'), + '"127.0.0.1" must not be an IP address', +)); + +test('Scenario #3', expectMessage( + static fn() => v::ip('127.0.1.*')->assert('127.0.0.1'), + '"127.0.0.1" must be an IP address in the 127.0.1.0-127.0.1.255 range', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::ip('127.0.1.*'))->assert('127.0.1.1'), + '"127.0.1.1" must not be an IP address in the 127.0.1.0-127.0.1.255 range', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::ip()->assert('257.0.0.1'), + '- "257.0.0.1" must be an IP address', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::ip())->assert('127.0.0.1'), + '- "127.0.0.1" must not be an IP address', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::ip('127.0.1.*')->assert('127.0.0.1'), + '- "127.0.0.1" must be an IP address in the 127.0.1.0-127.0.1.255 range', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::ip('127.0.1.*'))->assert('127.0.1.1'), + '- "127.0.1.1" must not be an IP address in the 127.0.1.0-127.0.1.255 range', +)); diff --git a/tests/feature/Rules/IsbnTest.php b/tests/feature/Rules/IsbnTest.php new file mode 100644 index 000000000..ee63ec728 --- /dev/null +++ b/tests/feature/Rules/IsbnTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::isbn()->assert('ISBN-12: 978-0-596-52068-7'), + '"ISBN-12: 978-0-596-52068-7" must be a valid ISBN', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::isbn())->assert('ISBN-13: 978-0-596-52068-7'), + '"ISBN-13: 978-0-596-52068-7" must not be a valid ISBN', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::isbn()->assert('978 10 596 52068 7'), + '- "978 10 596 52068 7" must be a valid ISBN', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::isbn())->assert('978 0 596 52068 7'), + '- "978 0 596 52068 7" must not be a valid ISBN', +)); diff --git a/tests/feature/Rules/IterableTypeTest.php b/tests/feature/Rules/IterableTypeTest.php new file mode 100644 index 000000000..accf6c396 --- /dev/null +++ b/tests/feature/Rules/IterableTypeTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::iterableType()->assert(null), + '`null` must be iterable', + '- `null` must be iterable', + ['iterableType' => '`null` must be iterable',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::iterableType())->assert([1, 2, 3]), + '`[1, 2, 3]` must not iterable', + '- `[1, 2, 3]` must not iterable', + ['notIterableType' => '`[1, 2, 3]` must not iterable',] +)); + +test('With template', expectAll( + static fn() => v::iterableType()->assert(null, 'Not an iterable at all'), + 'Not an iterable at all', + '- Not an iterable at all', + ['iterableType' => 'Not an iterable at all',] +)); + +test('With name', expectAll( + static fn() => v::iterableType()->setName('Options')->assert(null), + 'Options must be iterable', + '- Options must be iterable', + ['iterableType' => 'Options must be iterable',] +)); diff --git a/tests/feature/Rules/IterableValTest.php b/tests/feature/Rules/IterableValTest.php new file mode 100644 index 000000000..27153f016 --- /dev/null +++ b/tests/feature/Rules/IterableValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::iterableVal()->assert(3), + '3 must be an iterable value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::iterableVal())->assert([2, 3]), + '`[2, 3]` must not be an iterable value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::iterableVal()->assert('String'), + '- "String" must be an iterable value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::iterableVal())->assert(new stdClass()), + '- `stdClass {}` must not be an iterable value', +)); diff --git a/tests/feature/Rules/JsonTest.php b/tests/feature/Rules/JsonTest.php new file mode 100644 index 000000000..66760dcb3 --- /dev/null +++ b/tests/feature/Rules/JsonTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::json()->assert(false), + '`false` must be a valid JSON string', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::json())->assert('{"foo": "bar", "number":1}'), + '"{\\"foo\\": \\"bar\\", \\"number\\":1}" must not be a valid JSON string', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::json()->assert(new stdClass()), + '- `stdClass {}` must be a valid JSON string', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::json())->assert('{}'), + '- "{}" must not be a valid JSON string', +)); diff --git a/tests/feature/Rules/KeyExistsTest.php b/tests/feature/Rules/KeyExistsTest.php new file mode 100644 index 000000000..8c571c226 --- /dev/null +++ b/tests/feature/Rules/KeyExistsTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default mode', expectAll( + static fn() => v::keyExists('foo')->assert(['bar' => 'baz']), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('Inverted mode', expectAll( + static fn() => v::not(v::keyExists('foo'))->assert(['foo' => 'baz']), + 'foo must not be present', + '- foo must not be present', + ['foo' => 'foo must not be present',] +)); + +test('Custom name', expectAll( + static fn() => v::keyExists('foo')->setName('Custom name')->assert(['bar' => 'baz']), + 'Custom name must be present', + '- Custom name must be present', + ['foo' => 'Custom name must be present',] +)); + +test('Custom template', expectAll( + static fn() => v::keyExists('foo')->assert(['bar' => 'baz'], 'Custom template for `{{name}}`'), + 'Custom template for `foo`', + '- Custom template for `foo`', + ['foo' => 'Custom template for `foo`',] +)); diff --git a/tests/feature/Rules/KeyOptionalTest.php b/tests/feature/Rules/KeyOptionalTest.php new file mode 100644 index 000000000..fe748c8eb --- /dev/null +++ b/tests/feature/Rules/KeyOptionalTest.php @@ -0,0 +1,78 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::keyOptional('foo', v::intType())->assert(['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::keyOptional('foo', v::intType()))->assert(['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('Inverted with missing key', expectAll( + static fn() => v::not(v::keyOptional('foo', v::intType()))->assert([]), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('With wrapped name, default', expectAll( + static fn() => v::keyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper')->assert(['foo' => 'string']), + 'Wrapped must be an integer', + '- Wrapped must be an integer', + ['foo' => 'Wrapped must be an integer',] +)); + +test('With wrapped name, inverted', expectAll( + static fn() => v::not(v::keyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not')->assert(['foo' => 12]), + 'Wrapped must not be an integer', + '- Wrapped must not be an integer', + ['foo' => 'Wrapped must not be an integer',] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::keyOptional('foo', v::intType())->setName('Wrapper')->assert(['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::keyOptional('foo', v::intType())->setName('Wrapper'))->setName('Not')->assert(['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With "Not" name, inverted', expectAll( + static fn() => v::not(v::keyOptional('foo', v::intType()))->setName('Not')->assert(['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With template, default', expectAll( + static fn() => v::keyOptional('foo', v::intType())->assert(['foo' => 'string'], 'That key is off-key'), + 'That key is off-key', + '- That key is off-key', + ['foo' => 'That key is off-key',] +)); + +test('With template, inverted', expectAll( + static fn() => v::not(v::keyOptional('foo', v::intType()))->assert(['foo' => 12], 'No off-key key'), + 'No off-key key', + '- No off-key key', + ['foo' => 'No off-key key',] +)); diff --git a/tests/feature/Rules/KeySetTest.php b/tests/feature/Rules/KeySetTest.php new file mode 100644 index 000000000..b97a2519b --- /dev/null +++ b/tests/feature/Rules/KeySetTest.php @@ -0,0 +1,215 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('one rule / one failed', expectAll( + static fn() => v::keySet(v::key('foo', v::intType()))->assert(['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('one rule / one missing key', expectAll( + static fn() => v::keySet(v::keyExists('foo'))->assert([]), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('one rule / one extra key', expectAll( + static fn() => v::keySet(v::keyExists('foo'))->assert(['foo' => 42, 'bar' => 'string']), + 'bar must not be present', + '- bar must not be present', + ['bar' => 'bar must not be present',] +)); + +test('one rule / one extra key / one missing key', expectAll( + static fn() => v::keySet(v::keyExists('foo'))->assert(['bar' => true]), + 'foo must be present', + <<<'MESSAGE' + - `["bar": true]` contains both missing and extra keys + - foo must be present + - bar must not be present + MESSAGE, + [ + '__root__' => '`["bar": true]` contains both missing and extra keys', + 'foo' => 'foo must be present', + 'bar' => 'bar must not be present', + ] +)); + +test('one rule / two extra keys', expectAll( + static fn() => v::keySet(v::keyExists('foo'))->assert(['foo' => 42, 'bar' => 'string', 'baz' => true]), + 'bar must not be present', + <<<'MESSAGE' + - `["foo": 42, "bar": "string", "baz": true]` contains extra keys + - bar must not be present + - baz must not be present + MESSAGE, + [ + '__root__' => '`["foo": 42, "bar": "string", "baz": true]` contains extra keys', + 'bar' => 'bar must not be present', + 'baz' => 'baz must not be present', + ] +)); + +test('one rule / more than ten extra keys', expectAll( + static fn() => v::keySet(v::keyExists('foo')) + ->assert([ + 'foo' => 42, + 'bar' => 'string', + 'baz' => true, + 'qux' => false, + 'quux' => 42, + 'corge' => 'string', + 'grault' => true, + 'garply' => false, + 'waldo' => 42, + 'fred' => 'string', + 'plugh' => true, + 'xyzzy' => false, + 'thud' => 42, + ]), + 'bar must not be present', + <<<'MESSAGE' + - `["foo": 42, "bar": "string", "baz": true, "qux": false, "quux": 42, ...]` contains extra keys + - bar must not be present + - baz must not be present + - qux must not be present + - quux must not be present + - corge must not be present + - grault must not be present + - garply must not be present + - waldo must not be present + - fred must not be present + - plugh must not be present + MESSAGE, + [ + '__root__' => '`["foo": 42, "bar": "string", "baz": true, "qux": false, "quux": 42, ...]` contains extra keys', + 'bar' => 'bar must not be present', + 'baz' => 'baz must not be present', + 'qux' => 'qux must not be present', + 'quux' => 'quux must not be present', + 'corge' => 'corge must not be present', + 'grault' => 'grault must not be present', + 'garply' => 'garply must not be present', + 'waldo' => 'waldo must not be present', + 'fred' => 'fred must not be present', + 'plugh' => 'plugh must not be present', + ] +)); + +test('multiple rules / one failed', expectAll( + static fn() => v::keySet(v::keyExists('foo'), v::keyExists('bar'))->assert(['foo' => 42]), + 'bar must be present', + '- bar must be present', + ['bar' => 'bar must be present',] +)); + +test('multiple rules / all failed', expectAll( + static fn() => v::keySet(v::keyExists('foo'), v::keyExists('bar'))->assert([]), + 'foo must be present', + <<<'MESSAGE' + - `[]` contains missing keys + - foo must be present + - bar must be present + MESSAGE, + [ + '__root__' => '`[]` contains missing keys', + 'foo' => 'foo must be present', + 'bar' => 'bar must be present', + ] +)); + +test('multiple rules / one extra key', expectAll( + static fn() => v::keySet( + v::keyExists('foo'), + v::keyExists('bar') + )->assert(['foo' => 42, 'bar' => 'string', 'baz' => true]), + 'baz must not be present', + '- baz must not be present', + ['baz' => 'baz must not be present',] +)); + +test('multiple rules / one extra key / one missing', expectAll( + static fn() => v::keySet( + v::keyExists('foo'), + v::keyExists('bar') + )->assert(['bar' => 'string', 'baz' => true]), + 'foo must be present', + <<<'MESSAGE' + - `["bar": "string", "baz": true]` contains both missing and extra keys + - foo must be present + - baz must not be present + MESSAGE, + [ + '__root__' => '`["bar": "string", "baz": true]` contains both missing and extra keys', + 'foo' => 'foo must be present', + 'baz' => 'baz must not be present', + ] +)); + +test('multiple rules / two extra keys', expectAll( + static fn() => v::keySet( + v::keyExists('foo'), + v::keyExists('bar'), + v::keyOptional('qux', v::intType()) + )->assert(['foo' => 42, 'bar' => 'string', 'baz' => true, 'qux' => false]), + 'qux must be an integer', + <<<'MESSAGE' + - `["foo": 42, "bar": "string", "baz": true, "qux": false]` contains extra keys + - qux must be an integer + - baz must not be present + MESSAGE, + [ + '__root__' => '`["foo": 42, "bar": "string", "baz": true, "qux": false]` contains extra keys', + 'qux' => 'qux must be an integer', + 'baz' => 'baz must not be present', + ] +)); + +test('multiple rules / all failed validation', expectAll( + static fn() => v::keySet( + v::key('foo', v::intType()), + v::key('bar', v::intType()), + v::key('baz', v::intType()) + ) + ->assert(['foo' => 42, 'bar' => 'string', 'baz' => true]), + 'bar must be an integer', + <<<'MESSAGE' + - `["foo": 42, "bar": "string", "baz": true]` validation failed + - bar must be an integer + - baz must be an integer + MESSAGE, + [ + '__root__' => '`["foo": 42, "bar": "string", "baz": true]` validation failed', + 'bar' => 'bar must be an integer', + 'baz' => 'baz must be an integer', + ] +)); + +test('multiple rules / single missing key / single failed validation', expectAll( + static fn() => v::keySet( + v::create() + ->key('foo', v::intType()) + ->key('bar', v::intType()) + ->key('baz', v::intType()) + ) + ->assert(['foo' => 42, 'bar' => 'string']), + 'bar must be an integer', + <<<'MESSAGE' + - `["foo": 42, "bar": "string"]` contains missing keys + - bar must be an integer + - baz must be present + MESSAGE, + [ + '__root__' => '`["foo": 42, "bar": "string"]` contains missing keys', + 'bar' => 'bar must be an integer', + 'baz' => 'baz must be present', + ] +)); diff --git a/tests/feature/Rules/KeyTest.php b/tests/feature/Rules/KeyTest.php new file mode 100644 index 000000000..295975c07 --- /dev/null +++ b/tests/feature/Rules/KeyTest.php @@ -0,0 +1,99 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Missing key', expectAll( + static fn() => v::key('foo', v::intType())->assert([]), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('Default', expectAll( + static fn() => v::key('foo', v::intType())->assert(['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::key('foo', v::intType()))->assert(['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('Double-inverted with missing key', expectAll( + static fn() => v::not(v::not(v::key('foo', v::intType())))->assert([]), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('With wrapped name, missing key', expectAll( + static fn() => v::key('foo', v::intType()->setName('Wrapped'))->setName('Wrapper')->assert([]), + 'Wrapped must be present', + '- Wrapped must be present', + ['foo' => 'Wrapped must be present',] +)); + +test('With wrapped name, default', expectAll( + static fn() => v::key('foo', v::intType()->setName('Wrapped'))->setName('Wrapper')->assert(['foo' => 'string']), + 'Wrapped must be an integer', + '- Wrapped must be an integer', + ['foo' => 'Wrapped must be an integer',] +)); + +test('With wrapped name, inverted', expectAll( + static fn() => v::not(v::key('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not')->assert(['foo' => 12]), + 'Wrapped must not be an integer', + '- Wrapped must not be an integer', + ['foo' => 'Wrapped must not be an integer',] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::key('foo', v::intType())->setName('Wrapper')->assert(['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('With wrapper name, missing key', expectAll( + static fn() => v::key('foo', v::intType())->setName('Wrapper')->assert([]), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::key('foo', v::intType())->setName('Wrapper'))->setName('Not')->assert(['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With "Not" name, inverted', expectAll( + static fn() => v::not(v::key('foo', v::intType()))->setName('Not')->assert(['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With template, default', expectAll( + static fn() => v::key('foo', v::intType())->assert(['foo' => 'string'], 'That key is off-key'), + 'That key is off-key', + '- That key is off-key', + ['foo' => 'That key is off-key',] +)); + +test('With template, inverted', expectAll( + static fn() => v::not(v::key('foo', v::intType()))->assert(['foo' => 12], 'No off-key key'), + 'No off-key key', + '- No off-key key', + ['foo' => 'No off-key key',] +)); diff --git a/tests/feature/Rules/LanguageCodeTest.php b/tests/feature/Rules/LanguageCodeTest.php new file mode 100644 index 000000000..66ddf3a27 --- /dev/null +++ b/tests/feature/Rules/LanguageCodeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::languageCode()->assert(null), + '`null` must be a valid language code', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::languageCode())->assert('pt'), + '"pt" must not be a valid language code', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::languageCode()->assert('por'), + '- "por" must be a valid language code', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::languageCode())->assert('en'), + '- "en" must not be a valid language code', +)); diff --git a/tests/feature/Rules/LazyTest.php b/tests/feature/Rules/LazyTest.php new file mode 100644 index 000000000..a50fbcb15 --- /dev/null +++ b/tests/feature/Rules/LazyTest.php @@ -0,0 +1,64 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::lazy(static fn() => v::intType())->assert(true), + '`true` must be an integer', + '- `true` must be an integer', + ['intType' => '`true` must be an integer',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::lazy(static fn() => v::intType()))->assert(2), + '2 must not be an integer', + '- 2 must not be an integer', + ['notIntType' => '2 must not be an integer',] +)); + +test('With created name, default', expectAll( + static fn() => v::lazy(static fn() => v::intType()->setName('Created'))->setName('Wrapper')->assert(true), + 'Created must be an integer', + '- Created must be an integer', + ['intType' => 'Created must be an integer',] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::lazy(static fn() => v::intType())->setName('Wrapper')->assert(true), + 'Wrapper must be an integer', + '- Wrapper must be an integer', + ['intType' => 'Wrapper must be an integer',] +)); + +test('With created name, inverted', expectAll( + static fn() => v::not(v::lazy(static fn() => v::intType()->setName('Created'))->setName('Wrapped'))->setName('Not')->assert(2), + 'Created must not be an integer', + '- Created must not be an integer', + ['notIntType' => 'Created must not be an integer',] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::lazy(static fn() => v::intType())->setName('Wrapped'))->setName('Not')->assert(2), + 'Wrapped must not be an integer', + '- Wrapped must not be an integer', + ['notIntType' => 'Wrapped must not be an integer',] +)); + +test('With not name, inverted', expectAll( + static fn() => v::not(v::lazy(static fn() => v::intType()))->setName('Not')->assert(2), + 'Not must not be an integer', + '- Not must not be an integer', + ['notIntType' => 'Not must not be an integer',] +)); + +test('With template, default', expectAll( + static fn() => v::lazy(static fn() => v::intType())->assert(true, 'Lazy lizards lounging like lords in the local lagoon'), + 'Lazy lizards lounging like lords in the local lagoon', + '- Lazy lizards lounging like lords in the local lagoon', + ['intType' => 'Lazy lizards lounging like lords in the local lagoon',] +)); diff --git a/tests/feature/Rules/LeapDateTest.php b/tests/feature/Rules/LeapDateTest.php new file mode 100644 index 000000000..ad6fcf1b6 --- /dev/null +++ b/tests/feature/Rules/LeapDateTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::leapDate('Y-m-d')->assert('1989-02-29'), + '"1989-02-29" must be a valid leap date', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::leapDate('Y-m-d'))->assert('1988-02-29'), + '"1988-02-29" must not be a leap date', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::leapDate('Y-m-d')->assert('1990-02-29'), + '- "1990-02-29" must be a valid leap date', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::leapDate('Y-m-d'))->assert('1992-02-29'), + '- "1992-02-29" must not be a leap date', +)); diff --git a/tests/feature/Rules/LeapYearTest.php b/tests/feature/Rules/LeapYearTest.php new file mode 100644 index 000000000..e7b714185 --- /dev/null +++ b/tests/feature/Rules/LeapYearTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::leapYear()->assert('2009'), + '"2009" must be a valid leap year', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::leapYear())->assert('2008'), + '"2008" must not be a leap year', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::leapYear()->assert('2009-02-29'), + '- "2009-02-29" must be a valid leap year', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::leapYear())->assert('2008'), + '- "2008" must not be a leap year', +)); diff --git a/tests/feature/Rules/LengthTest.php b/tests/feature/Rules/LengthTest.php new file mode 100644 index 000000000..0acce23ed --- /dev/null +++ b/tests/feature/Rules/LengthTest.php @@ -0,0 +1,43 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::length(v::equals(3))->assert('tulip'), + 'The length of "tulip" must be equal to 3', + '- The length of "tulip" must be equal to 3', + ['lengthEquals' => 'The length of "tulip" must be equal to 3',] +)); + +test('Inverted wrapped', expectAll( + static fn() => v::length(v::not(v::equals(4)))->assert('rose'), + 'The length of "rose" must not be equal to 4', + '- The length of "rose" must not be equal to 4', + ['lengthNotEquals' => 'The length of "rose" must not be equal to 4',] +)); + +test('Inverted wrapper', expectAll( + static fn() => v::not(v::length(v::equals(4)))->assert('fern'), + 'The length of "fern" must not be equal to 4', + '- The length of "fern" must not be equal to 4', + ['notLengthEquals' => 'The length of "fern" must not be equal to 4',] +)); + +test('With template', expectAll( + static fn() => v::length(v::equals(3))->assert('azalea', 'This is a template'), + 'This is a template', + '- This is a template', + ['lengthEquals' => 'This is a template',] +)); + +test('With wrapper name', expectAll( + static fn() => v::length(v::equals(3))->setName('Cactus')->assert('peyote'), + 'The length of Cactus must be equal to 3', + '- The length of Cactus must be equal to 3', + ['lengthEquals' => 'The length of Cactus must be equal to 3',] +)); diff --git a/tests/feature/Rules/LessThanOrEqualTest.php b/tests/feature/Rules/LessThanOrEqualTest.php new file mode 100644 index 000000000..c197f65ea --- /dev/null +++ b/tests/feature/Rules/LessThanOrEqualTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::lessThanOrEqual(10)->assert(11), + '11 must be less than or equal to 10', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::lessThanOrEqual(10))->assert(5), + '5 must be greater than 10', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::lessThanOrEqual('today')->assert('tomorrow'), + '- "tomorrow" must be less than or equal to "today"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::lessThanOrEqual('b'))->assert('a'), + '- "a" must be greater than "b"', +)); diff --git a/tests/feature/Rules/LessThanTest.php b/tests/feature/Rules/LessThanTest.php new file mode 100644 index 000000000..60560644d --- /dev/null +++ b/tests/feature/Rules/LessThanTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::lessThan(12)->assert(21), + '21 must be less than 12', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::lessThan('today'))->assert('yesterday'), + '"yesterday" must not be less than "today"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::lessThan('1988-09-09')->assert('2018-09-09'), + '- "2018-09-09" must be less than "1988-09-09"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::lessThan('b'))->assert('a'), + '- "a" must not be less than "b"', +)); diff --git a/tests/feature/Rules/LowercaseTest.php b/tests/feature/Rules/LowercaseTest.php new file mode 100644 index 000000000..b7c5c817c --- /dev/null +++ b/tests/feature/Rules/LowercaseTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::lowercase()->assert('UPPERCASE'), + '"UPPERCASE" must contain only lowercase letters', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::lowercase())->assert('lowercase'), + '"lowercase" must not contain only lowercase letters', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::lowercase()->assert('UPPERCASE'), + '- "UPPERCASE" must contain only lowercase letters', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::lowercase())->assert('lowercase'), + '- "lowercase" must not contain only lowercase letters', +)); diff --git a/tests/feature/Rules/LuhnTest.php b/tests/feature/Rules/LuhnTest.php new file mode 100644 index 000000000..2f46d3b12 --- /dev/null +++ b/tests/feature/Rules/LuhnTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::luhn()->assert('2222400041240021'), + '"2222400041240021" must be a valid Luhn number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::luhn())->assert('2223000048400011'), + '"2223000048400011" must not be a valid Luhn number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::luhn()->assert('340316193809334'), + '- "340316193809334" must be a valid Luhn number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::luhn())->assert('6011000990139424'), + '- "6011000990139424" must not be a valid Luhn number', +)); diff --git a/tests/feature/Rules/MacAddressTest.php b/tests/feature/Rules/MacAddressTest.php new file mode 100644 index 000000000..7565d482e --- /dev/null +++ b/tests/feature/Rules/MacAddressTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::macAddress()->assert('00-11222:33:44:55'), + '"00-11222:33:44:55" must be a valid MAC address', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::macAddress())->assert('00:11:22:33:44:55'), + '"00:11:22:33:44:55" must not be a valid MAC address', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::macAddress()->assert('90-bc-nk:1a-dd-cc'), + '- "90-bc-nk:1a-dd-cc" must be a valid MAC address', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::macAddress())->assert('AF:0F:bd:12:44:ba'), + '- "AF:0F:bd:12:44:ba" must not be a valid MAC address', +)); diff --git a/tests/feature/Rules/MaxTest.php b/tests/feature/Rules/MaxTest.php new file mode 100644 index 000000000..731bd5571 --- /dev/null +++ b/tests/feature/Rules/MaxTest.php @@ -0,0 +1,71 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Non-iterable', expectAll( + static fn() => v::max(v::negative())->assert(null), + '`null` must be iterable', + '- `null` must be iterable', + ['max' => '`null` must be iterable',] +)); + +test('Empty', expectAll( + static fn() => v::max(v::negative())->assert([]), + 'The value must not be empty', + '- The value must not be empty', + ['max' => 'The value must not be empty',] +)); + +test('Default', expectAll( + static fn() => v::max(v::negative())->assert([1, 2, 3]), + 'As the maximum of `[1, 2, 3]`, 3 must be a negative number', + '- As the maximum of `[1, 2, 3]`, 3 must be a negative number', + ['maxNegative' => 'As the maximum of `[1, 2, 3]`, 3 must be a negative number',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::max(v::negative()))->assert([-3, -2, -1]), + 'As the maximum of `[-3, -2, -1]`, -1 must not be a negative number', + '- As the maximum of `[-3, -2, -1]`, -1 must not be a negative number', + ['notMaxNegative' => 'As the maximum of `[-3, -2, -1]`, -1 must not be a negative number',] +)); + +test('With wrapped name, default', expectAll( + static fn() => v::max(v::negative()->setName('Wrapped'))->setName('Wrapper')->assert([1, 2, 3]), + 'The maximum of Wrapped must be a negative number', + '- The maximum of Wrapped must be a negative number', + ['maxNegative' => 'The maximum of Wrapped must be a negative number',] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::max(v::negative())->setName('Wrapper')->assert([1, 2, 3]), + 'The maximum of Wrapper must be a negative number', + '- The maximum of Wrapper must be a negative number', + ['maxNegative' => 'The maximum of Wrapper must be a negative number',] +)); + +test('With wrapped name, inverted', expectAll( + static fn() => v::not(v::max(v::negative()->setName('Wrapped')))->setName('Wrapper')->assert([-3, -2, -1]), + 'The maximum of Wrapped must not be a negative number', + '- The maximum of Wrapped must not be a negative number', + ['notMaxNegative' => 'The maximum of Wrapped must not be a negative number',] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::max(v::negative()))->setName('Wrapper')->assert([-3, -2, -1]), + 'The maximum of Wrapper must not be a negative number', + '- The maximum of Wrapper must not be a negative number', + ['notMaxNegative' => 'The maximum of Wrapper must not be a negative number',] +)); + +test('With template, default', expectAll( + static fn() => v::max(v::negative())->assert([1, 2, 3], 'The maximum of the value is not what we expect'), + 'The maximum of the value is not what we expect', + '- The maximum of the value is not what we expect', + ['maxNegative' => 'The maximum of the value is not what we expect',] +)); diff --git a/tests/feature/Rules/MimetypeTest.php b/tests/feature/Rules/MimetypeTest.php new file mode 100644 index 000000000..9661f42ba --- /dev/null +++ b/tests/feature/Rules/MimetypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::mimetype('image/png')->assert('image.png'), + '"image.png" must have the "image/png" MIME type', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::mimetype('image/png'))->assert('tests/fixtures/valid-image.png'), + '"tests/fixtures/valid-image.png" must not have the "image/png" MIME type', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::mimetype('image/png')->assert('tests/fixtures/invalid-image.png'), + '- "tests/fixtures/invalid-image.png" must have the "image/png" MIME type', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::mimetype('image/png'))->assert('tests/fixtures/valid-image.png'), + '- "tests/fixtures/valid-image.png" must not have the "image/png" MIME type', +)); diff --git a/tests/feature/Rules/MinTest.php b/tests/feature/Rules/MinTest.php new file mode 100644 index 000000000..2a531decd --- /dev/null +++ b/tests/feature/Rules/MinTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::min(v::equals(1))->assert([2, 3]), + 'As the minimum from `[2, 3]`, 2 must be equal to 1', + '- As the minimum from `[2, 3]`, 2 must be equal to 1', + ['minEquals' => 'As the minimum from `[2, 3]`, 2 must be equal to 1',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::min(v::equals(1)))->assert([1, 2, 3]), + 'As the minimum from `[1, 2, 3]`, 1 must not be equal to 1', + '- As the minimum from `[1, 2, 3]`, 1 must not be equal to 1', + ['notMinEquals' => 'As the minimum from `[1, 2, 3]`, 1 must not be equal to 1',] +)); + +test('With template', expectAll( + static fn() => v::min(v::equals(1))->assert([2, 3], 'That did not go as planned'), + 'That did not go as planned', + '- That did not go as planned', + ['minEquals' => 'That did not go as planned',] +)); + +test('With name', expectAll( + static fn() => v::min(v::equals(1))->setName('Options')->assert([2, 3]), + 'The minimum from Options must be equal to 1', + '- The minimum from Options must be equal to 1', + ['minEquals' => 'The minimum from Options must be equal to 1',] +)); diff --git a/tests/feature/Rules/MultipleTest.php b/tests/feature/Rules/MultipleTest.php new file mode 100644 index 000000000..8521b3193 --- /dev/null +++ b/tests/feature/Rules/MultipleTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::multiple(3)->assert(22), + '22 must be a multiple of 3', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::multiple(3))->assert(9), + '9 must not be a multiple of 3', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::multiple(2)->assert(5), + '- 5 must be a multiple of 2', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::multiple(5))->assert(25), + '- 25 must not be a multiple of 5', +)); diff --git a/tests/feature/Rules/NegativeTest.php b/tests/feature/Rules/NegativeTest.php new file mode 100644 index 000000000..9cd9d006e --- /dev/null +++ b/tests/feature/Rules/NegativeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::negative()->assert(16), + '16 must be a negative number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::negative())->assert(-10), + '-10 must not be a negative number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::negative()->assert('a'), + '- "a" must be a negative number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::negative())->assert('-144'), + '- "-144" must not be a negative number', +)); diff --git a/tests/feature/Rules/NfeAccessKeyTest.php b/tests/feature/Rules/NfeAccessKeyTest.php new file mode 100644 index 000000000..471856372 --- /dev/null +++ b/tests/feature/Rules/NfeAccessKeyTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::nfeAccessKey()->assert('31841136830118868211870485416765268625116906'), + '"31841136830118868211870485416765268625116906" must be a valid NFe access key', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::nfeAccessKey())->assert('52060433009911002506550120000007800267301615'), + '"52060433009911002506550120000007800267301615" must not be a valid NFe access key', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::nfeAccessKey()->assert('31841136830118868211870485416765268625116906'), + '- "31841136830118868211870485416765268625116906" must be a valid NFe access key', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::nfeAccessKey())->assert('52060433009911002506550120000007800267301615'), + '- "52060433009911002506550120000007800267301615" must not be a valid NFe access key', +)); diff --git a/tests/feature/Rules/NifTest.php b/tests/feature/Rules/NifTest.php new file mode 100644 index 000000000..dd5edb695 --- /dev/null +++ b/tests/feature/Rules/NifTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::nif()->assert('06357771Q'), + '"06357771Q" must be a valid NIF', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::nif())->assert('71110316C'), + '"71110316C" must not be a valid NIF', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::nif()->assert('06357771Q'), + '- "06357771Q" must be a valid NIF', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::nif())->assert('R1332622H'), + '- "R1332622H" must not be a valid NIF', +)); diff --git a/tests/feature/Rules/NipTest.php b/tests/feature/Rules/NipTest.php new file mode 100644 index 000000000..36161e2c6 --- /dev/null +++ b/tests/feature/Rules/NipTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +require_once 'vendor/autoload.php'; + +test('Scenario #1', expectMessage( + static fn() => v::nip()->assert('1645865778'), + '"1645865778" must be a valid Polish VAT identification number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::nip())->assert('1645865777'), + '"1645865777" must not be a valid Polish VAT identification number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::nip()->assert('1645865778'), + '- "1645865778" must be a valid Polish VAT identification number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::nip())->assert('1645865777'), + '- "1645865777" must not be a valid Polish VAT identification number', +)); diff --git a/tests/feature/Rules/NoTest.php b/tests/feature/Rules/NoTest.php new file mode 100644 index 000000000..757d55454 --- /dev/null +++ b/tests/feature/Rules/NoTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::not(v::no())->assert('No'), + '"No" must not be similar to "No"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::no()->assert('Yes'), + '"Yes" must be similar to "No"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::not(v::no())->assert('No'), + '- "No" must not be similar to "No"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::no()->assert('Yes'), + '- "Yes" must be similar to "No"', +)); diff --git a/tests/feature/Rules/NoWhitespaceTest.php b/tests/feature/Rules/NoWhitespaceTest.php new file mode 100644 index 000000000..c0bbfa014 --- /dev/null +++ b/tests/feature/Rules/NoWhitespaceTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::noWhitespace()->assert('w poiur'), + '"w poiur" must not contain whitespaces', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::noWhitespace())->assert('wpoiur'), + '"wpoiur" must contain at least one whitespace', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::noWhitespace()->assert('w poiur'), + '- "w poiur" must not contain whitespaces', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::noWhitespace())->assert('wpoiur'), + '- "wpoiur" must contain at least one whitespace', +)); diff --git a/tests/feature/Rules/NoneOfTest.php b/tests/feature/Rules/NoneOfTest.php new file mode 100644 index 000000000..75fe7bae8 --- /dev/null +++ b/tests/feature/Rules/NoneOfTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::noneOf(v::intType(), v::positive())->assert(42), + '42 must not be an integer', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::noneOf(v::intType(), v::positive()))->assert('-1'), + '"-1" must be an integer', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::noneOf(v::intType(), v::positive())->assert(42), + <<<'MESSAGE' +- None of these rules must pass for 42 + - 42 must not be an integer + - 42 must not be a positive number +MESSAGE, +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::noneOf(v::intType(), v::positive()))->assert('-1'), + <<<'MESSAGE' +- All of these rules must pass for "-1" + - "-1" must be an integer + - "-1" must be a positive number +MESSAGE, +)); diff --git a/tests/feature/Rules/NotBlankTest.php b/tests/feature/Rules/NotBlankTest.php new file mode 100644 index 000000000..ef7ff303b --- /dev/null +++ b/tests/feature/Rules/NotBlankTest.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::notBlank()->assert(null), + 'The value must not be blank', +)); + +test('Scenario #2', expectMessage( + static fn() => v::notBlank()->setName('Field')->assert(null), + 'Field must not be blank', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::notBlank())->assert(1), + '1 must be blank', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::notBlank()->assert(''), + '- The value must not be blank', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::notBlank()->setName('Field')->assert(''), + '- Field must not be blank', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::notBlank())->assert([1]), + '- `[1]` must be blank', +)); diff --git a/tests/feature/Rules/NotEmojiTest.php b/tests/feature/Rules/NotEmojiTest.php new file mode 100644 index 000000000..ca8652643 --- /dev/null +++ b/tests/feature/Rules/NotEmojiTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::notEmoji()->assert('🍕'), + '"🍕" must not contain an emoji', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::notEmoji())->assert('AB'), + '"AB" must contain an emoji', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::notEmoji()->assert('🏄'), + '- "🏄" must not contain an emoji', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::notEmoji())->assert('YZ'), + '- "YZ" must contain an emoji', +)); diff --git a/tests/feature/Rules/NotEmptyTest.php b/tests/feature/Rules/NotEmptyTest.php new file mode 100644 index 000000000..70ebff12f --- /dev/null +++ b/tests/feature/Rules/NotEmptyTest.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::notEmpty()->assert(null), + 'The value must not be empty', +)); + +test('Scenario #2', expectMessage( + static fn() => v::notEmpty()->setName('Field')->assert(null), + 'Field must not be empty', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::notEmpty())->assert(1), + '1 must be empty', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::notEmpty()->assert(''), + '- The value must not be empty', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::notEmpty()->setName('Field')->assert(''), + '- Field must not be empty', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::notEmpty())->assert([1]), + '- `[1]` must be empty', +)); diff --git a/tests/feature/Rules/NotUndefTest.php b/tests/feature/Rules/NotUndefTest.php new file mode 100644 index 000000000..3175aa724 --- /dev/null +++ b/tests/feature/Rules/NotUndefTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::notUndef()->assert(null), + 'The value must be defined', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::notUndef())->assert(0), + 'The value must be undefined', +)); + +test('Scenario #3', expectMessage( + static fn() => v::notUndef()->setName('Field')->assert(null), + 'Field must be defined', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::notUndef()->setName('Field'))->assert([]), + 'Field must be undefined', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::notUndef()->assert(''), + '- The value must be defined', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::notUndef())->assert([]), + '- The value must be undefined', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::notUndef()->setName('Field')->assert(''), + '- Field must be defined', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::notUndef()->setName('Field'))->assert([]), + '- Field must be undefined', +)); diff --git a/tests/feature/Rules/NullOrTest.php b/tests/feature/Rules/NullOrTest.php new file mode 100644 index 000000000..07f482bba --- /dev/null +++ b/tests/feature/Rules/NullOrTest.php @@ -0,0 +1,111 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::nullOr(v::alpha())->assert(1234), + '1234 must contain only letters (a-z) or must be null', + '- 1234 must contain only letters (a-z) or must be null', + ['nullOrAlpha' => '1234 must contain only letters (a-z) or must be null',] +)); + +test('Inverted wrapper', expectAll( + static fn() => v::not(v::nullOr(v::alpha()))->assert('alpha'), + '"alpha" must not contain letters (a-z) and must not be null', + '- "alpha" must not contain letters (a-z) and must not be null', + ['notNullOrAlpha' => '"alpha" must not contain letters (a-z) and must not be null',] +)); + +test('Inverted wrapped', expectAll( + static fn() => v::nullOr(v::not(v::alpha()))->assert('alpha'), + '"alpha" must not contain letters (a-z) or must be null', + '- "alpha" must not contain letters (a-z) or must be null', + ['nullOrNotAlpha' => '"alpha" must not contain letters (a-z) or must be null',] +)); + +test('Inverted nullined', expectAll( + static fn() => v::not(v::nullOr(v::alpha()))->assert(null), + '`null` must not contain letters (a-z) and must not be null', + '- `null` must not contain letters (a-z) and must not be null', + ['notNullOrAlpha' => '`null` must not contain letters (a-z) and must not be null',] +)); + +test('Inverted nullined, wrapped name', expectAll( + static fn() => v::not(v::nullOr(v::alpha()->setName('Wrapped')))->assert(null), + 'Wrapped must not contain letters (a-z) and must not be null', + '- Wrapped must not contain letters (a-z) and must not be null', + ['notNullOrAlpha' => 'Wrapped must not contain letters (a-z) and must not be null',] +)); + +test('Inverted nullined, wrapper name', expectAll( + static fn() => v::not(v::nullOr(v::alpha())->setName('Wrapper'))->assert(null), + 'Wrapper must not contain letters (a-z) and must not be null', + '- Wrapper must not contain letters (a-z) and must not be null', + ['notNullOrAlpha' => 'Wrapper must not contain letters (a-z) and must not be null',] +)); + +test('Inverted nullined, not name', expectAll( + static fn() => v::not(v::nullOr(v::alpha()))->setName('Not')->assert(null), + 'Not must not contain letters (a-z) and must not be null', + '- Not must not contain letters (a-z) and must not be null', + ['notNullOrAlpha' => 'Not must not contain letters (a-z) and must not be null',] +)); + +test('With template', expectAll( + static fn() => v::nullOr(v::alpha())->assert(123, 'Nine nimble numismatists near Naples'), + 'Nine nimble numismatists near Naples', + '- Nine nimble numismatists near Naples', + ['nullOrAlpha' => 'Nine nimble numismatists near Naples',] +)); + +test('With array template', expectAll( + static fn() => v::nullOr(v::alpha())->assert(123, ['nullOrAlpha' => 'Next to nifty null notations']), + 'Next to nifty null notations', + '- Next to nifty null notations', + ['nullOrAlpha' => 'Next to nifty null notations',] +)); + +test('Inverted nullined with template', expectAll( + static fn() => v::not(v::nullOr(v::alpha()))->assert(null, ['notNullOrAlpha' => 'Next to nifty null notations']), + 'Next to nifty null notations', + '- Next to nifty null notations', + ['notNullOrAlpha' => 'Next to nifty null notations',] +)); + +test('Without subsequent result', expectAll( + static fn() => v::nullOr(v::alpha()->stringType())->assert(1234), + '1234 must contain only letters (a-z) or must be null', + <<<'MESSAGE' + - All of the required rules must pass for 1234 + - 1234 must contain only letters (a-z) or must be null + - 1234 must be a string or must be null + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1234', + 'nullOrAlpha' => '1234 must contain only letters (a-z) or must be null', + 'nullOrStringType' => '1234 must be a string or must be null', + ] +)); + +test('Without subsequent result with templates', expectAll( + static fn() => v::nullOr(v::alpha()->stringType())->assert(1234, [ + 'nullOrAlpha' => 'Should be nul or alpha', + 'nullOrStringType' => 'Should be nul or string type', + ]), + 'Should be nul or alpha', + <<<'MESSAGE' + - All of the required rules must pass for 1234 + - Should be nul or alpha + - Should be nul or string type + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1234', + 'nullOrAlpha' => 'Should be nul or alpha', + 'nullOrStringType' => 'Should be nul or string type', + ] +)); diff --git a/tests/feature/Rules/NullTypeTest.php b/tests/feature/Rules/NullTypeTest.php new file mode 100644 index 000000000..0218f712f --- /dev/null +++ b/tests/feature/Rules/NullTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::nullType()->assert(''), + '"" must be null', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::nullType())->assert(null), + '`null` must not be null', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::nullType()->assert(false), + '- `false` must be null', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::nullType())->assert(null), + '- `null` must not be null', +)); diff --git a/tests/feature/Rules/NumberTest.php b/tests/feature/Rules/NumberTest.php new file mode 100644 index 000000000..3c7e71219 --- /dev/null +++ b/tests/feature/Rules/NumberTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::number()->assert(acos(1.01)), + '`NaN` must be a valid number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::number())->assert(42), + '42 must not be a number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::number()->assert(NAN), + '- `NaN` must be a valid number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::number())->assert(42), + '- 42 must not be a number', +)); diff --git a/tests/feature/Rules/NumericValTest.php b/tests/feature/Rules/NumericValTest.php new file mode 100644 index 000000000..efa7bcc28 --- /dev/null +++ b/tests/feature/Rules/NumericValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::numericVal()->assert('a'), + '"a" must be a numeric value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::numericVal())->assert('1'), + '"1" must not be a numeric value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::numericVal()->assert('a'), + '- "a" must be a numeric value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::numericVal())->assert('1'), + '- "1" must not be a numeric value', +)); diff --git a/tests/feature/Rules/ObjectTypeTest.php b/tests/feature/Rules/ObjectTypeTest.php new file mode 100644 index 000000000..81f1ad5a9 --- /dev/null +++ b/tests/feature/Rules/ObjectTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::objectType()->assert([]), + '`[]` must be an object', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::objectType())->assert(new stdClass()), + '`stdClass {}` must not be an object', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::objectType()->assert('test'), + '- `test(?string $description = null, ?Closure $closure = null): Pest\\Support\\HigherOrderTapProxy|Pest\\PendingCalls\\Te ...` must be an object', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::objectType())->assert(new ArrayObject()), + '- `ArrayObject { getArrayCopy() => [] }` must not be an object', +)); diff --git a/tests/feature/Rules/OddTest.php b/tests/feature/Rules/OddTest.php new file mode 100644 index 000000000..51972a397 --- /dev/null +++ b/tests/feature/Rules/OddTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::odd()->assert(2), + '2 must be an odd number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::odd())->assert(7), + '7 must be an even number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::odd()->assert(2), + '- 2 must be an odd number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::odd())->assert(9), + '- 9 must be an even number', +)); diff --git a/tests/feature/Rules/PerfectSquareTest.php b/tests/feature/Rules/PerfectSquareTest.php new file mode 100644 index 000000000..a10544b05 --- /dev/null +++ b/tests/feature/Rules/PerfectSquareTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::perfectSquare()->assert(250), + '250 must be a perfect square number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::perfectSquare())->assert(9), + '9 must not be a perfect square number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::perfectSquare()->assert(7), + '- 7 must be a perfect square number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::perfectSquare())->assert(400), + '- 400 must not be a perfect square number', +)); diff --git a/tests/feature/Rules/PeselTest.php b/tests/feature/Rules/PeselTest.php new file mode 100644 index 000000000..14dd1ae32 --- /dev/null +++ b/tests/feature/Rules/PeselTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +require_once 'vendor/autoload.php'; + +test('Scenario #1', expectMessage( + static fn() => v::pesel()->assert('21120209251'), + '"21120209251" must be a valid PESEL', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::pesel())->assert('21120209256'), + '"21120209256" must not be a valid PESEL', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::pesel()->assert('21120209251'), + '- "21120209251" must be a valid PESEL', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::pesel())->assert('21120209256'), + '- "21120209256" must not be a valid PESEL', +)); diff --git a/tests/feature/Rules/PhoneTest.php b/tests/feature/Rules/PhoneTest.php new file mode 100644 index 000000000..6d30bead9 --- /dev/null +++ b/tests/feature/Rules/PhoneTest.php @@ -0,0 +1,43 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::phone()->assert('123'), + '"123" must be a valid telephone number', + '- "123" must be a valid telephone number', + ['phone' => '"123" must be a valid telephone number',] +)); + +test('Country-specific', expectAll( + static fn() => v::phone('BR')->assert('+1 650 253 00 00'), + '"+1 650 253 00 00" must be a valid telephone number for country Brazil', + '- "+1 650 253 00 00" must be a valid telephone number for country Brazil', + ['phone' => '"+1 650 253 00 00" must be a valid telephone number for country Brazil',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::phone())->assert('+55 11 91111 1111'), + '"+55 11 91111 1111" must not be a valid telephone number', + '- "+55 11 91111 1111" must not be a valid telephone number', + ['notPhone' => '"+55 11 91111 1111" must not be a valid telephone number',] +)); + +test('Default with name', expectAll( + static fn() => v::phone()->setName('Phone')->assert('123'), + 'Phone must be a valid telephone number', + '- Phone must be a valid telephone number', + ['phone' => 'Phone must be a valid telephone number',] +)); + +test('Country-specific with name', expectAll( + static fn() => v::phone('US')->setName('Phone')->assert('123'), + 'Phone must be a valid telephone number for country United States', + '- Phone must be a valid telephone number for country United States', + ['phone' => 'Phone must be a valid telephone number for country United States',] +)); diff --git a/tests/feature/Rules/PhplabelTest.php b/tests/feature/Rules/PhplabelTest.php new file mode 100644 index 000000000..3cfb6a783 --- /dev/null +++ b/tests/feature/Rules/PhplabelTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::phpLabel()->assert('f o o'), + '"f o o" must be a valid PHP label', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::phpLabel())->assert('correctOne'), + '"correctOne" must not be a valid PHP label', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::phpLabel()->assert('0wner'), + '- "0wner" must be a valid PHP label', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::phpLabel())->assert('Respect'), + '- "Respect" must not be a valid PHP label', +)); diff --git a/tests/feature/Rules/PisTest.php b/tests/feature/Rules/PisTest.php new file mode 100644 index 000000000..0689b37cf --- /dev/null +++ b/tests/feature/Rules/PisTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::pis()->assert('this thing'), + '"this thing" must be a valid PIS number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::pis())->assert('120.6671.406-4'), + '"120.6671.406-4" must not be a valid PIS number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::pis()->assert('your mother'), + '- "your mother" must be a valid PIS number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::pis())->assert('120.9378.174-5'), + '- "120.9378.174-5" must not be a valid PIS number', +)); diff --git a/tests/feature/Rules/PolishIdCardTest.php b/tests/feature/Rules/PolishIdCardTest.php new file mode 100644 index 000000000..38e8bad40 --- /dev/null +++ b/tests/feature/Rules/PolishIdCardTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +require_once 'vendor/autoload.php'; + +test('Scenario #1', expectMessage( + static fn() => v::polishIdCard()->assert('AYE205411'), + '"AYE205411" must be a valid Polish Identity Card number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::polishIdCard())->assert('AYE205410'), + '"AYE205410" must not be a valid Polish Identity Card number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::polishIdCard()->assert('AYE205411'), + '- "AYE205411" must be a valid Polish Identity Card number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::polishIdCard())->assert('AYE205410'), + '- "AYE205410" must not be a valid Polish Identity Card number', +)); diff --git a/tests/feature/Rules/PositiveTest.php b/tests/feature/Rules/PositiveTest.php new file mode 100644 index 000000000..b40104418 --- /dev/null +++ b/tests/feature/Rules/PositiveTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::positive()->assert(-10), + '-10 must be a positive number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::positive())->assert(16), + '16 must not be a positive number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::positive()->assert('a'), + '- "a" must be a positive number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::positive())->assert('165'), + '- "165" must not be a positive number', +)); diff --git a/tests/feature/Rules/PostalCodeTest.php b/tests/feature/Rules/PostalCodeTest.php new file mode 100644 index 000000000..0781a5f20 --- /dev/null +++ b/tests/feature/Rules/PostalCodeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::postalCode('BR')->assert('1057BV'), + '"1057BV" must be a valid postal code on "BR"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::postalCode('NL'))->assert('1057BV'), + '"1057BV" must not be a valid postal code on "NL"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::postalCode('BR')->assert('1057BV'), + '- "1057BV" must be a valid postal code on "BR"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::postalCode('NL'))->assert('1057BV'), + '- "1057BV" must not be a valid postal code on "NL"', +)); diff --git a/tests/feature/Rules/PrimeNumberTest.php b/tests/feature/Rules/PrimeNumberTest.php new file mode 100644 index 000000000..88873503a --- /dev/null +++ b/tests/feature/Rules/PrimeNumberTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::primeNumber()->assert(10), + '10 must be a prime number', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::primeNumber())->assert(3), + '3 must not be a prime number', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::primeNumber()->assert('Foo'), + '- "Foo" must be a prime number', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::primeNumber())->assert('+7'), + '- "+7" must not be a prime number', +)); diff --git a/tests/feature/Rules/PrintableTest.php b/tests/feature/Rules/PrintableTest.php new file mode 100644 index 000000000..2db461c58 --- /dev/null +++ b/tests/feature/Rules/PrintableTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::printable()->assert(''), + '"" must contain only printable characters', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::printable())->assert('abc'), + '"abc" must not contain printable characters', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::printable()->assert('foo' . chr(10) . 'bar'), + '- "foo\\nbar" must contain only printable characters', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::printable())->assert('$%asd'), + '- "$%asd" must not contain printable characters', +)); diff --git a/tests/feature/Rules/PropertyExistsTest.php b/tests/feature/Rules/PropertyExistsTest.php new file mode 100644 index 000000000..eb417ab1b --- /dev/null +++ b/tests/feature/Rules/PropertyExistsTest.php @@ -0,0 +1,36 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default mode', expectAll( + static fn() => v::propertyExists('foo')->assert((object) ['bar' => 'baz']), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('Inverted mode', expectAll( + static fn() => v::not(v::propertyExists('foo'))->assert((object) ['foo' => 'baz']), + 'foo must not be present', + '- foo must not be present', + ['foo' => 'foo must not be present',] +)); + +test('Custom name', expectAll( + static fn() => v::propertyExists('foo')->setName('Custom name')->assert((object) ['bar' => 'baz']), + 'Custom name must be present', + '- Custom name must be present', + ['foo' => 'Custom name must be present',] +)); + +test('Custom template', expectAll( + static fn() => v::propertyExists('foo')->assert((object) ['bar' => 'baz'], 'Custom template for `{{name}}`'), + 'Custom template for `foo`', + '- Custom template for `foo`', + ['foo' => 'Custom template for `foo`',] +)); diff --git a/tests/feature/Rules/PropertyOptionalTest.php b/tests/feature/Rules/PropertyOptionalTest.php new file mode 100644 index 000000000..7e21f5749 --- /dev/null +++ b/tests/feature/Rules/PropertyOptionalTest.php @@ -0,0 +1,83 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::propertyOptional('foo', v::intType())->assert((object) ['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::propertyOptional('foo', v::intType()))->assert((object) ['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('Inverted with missing property', expectAll( + static fn() => v::not(v::propertyOptional('foo', v::intType()))->assert(new stdClass()), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('With wrapped name, default', expectAll( + static fn() => v::propertyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper')->assert((object) ['foo' => 'string']), + 'Wrapped must be an integer', + '- Wrapped must be an integer', + ['foo' => 'Wrapped must be an integer',] +)); + +test('With wrapped name, inverted', expectAll( + static fn() => v::not(v::propertyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not')->assert((object) ['foo' => 12]), + 'Wrapped must not be an integer', + '- Wrapped must not be an integer', + ['foo' => 'Wrapped must not be an integer',] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::propertyOptional('foo', v::intType()) + ->setName('Wrapper') + ->assert((object) ['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::propertyOptional('foo', v::intType())->setName('Wrapper')) + ->setName('Not')->assert((object) ['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With "Not" name, inverted', expectAll( + static fn() => v::not(v::propertyOptional('foo', v::intType()))->setName('Not')->assert((object) ['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With template, default', expectAll( + static fn() => v::propertyOptional('foo', v::intType()) + ->assert((object) ['foo' => 'string'], 'Proper property planners plan precise property plots'), + 'Proper property planners plan precise property plots', + '- Proper property planners plan precise property plots', + ['foo' => 'Proper property planners plan precise property plots',] +)); + +test('With template, inverted', expectAll( + static fn() => v::not(v::propertyOptional('foo', v::intType())) + ->assert((object) ['foo' => 12], 'Not proving prudent property planning promotes prosperity'), + 'Not proving prudent property planning promotes prosperity', + '- Not proving prudent property planning promotes prosperity', + ['foo' => 'Not proving prudent property planning promotes prosperity',] +)); diff --git a/tests/feature/Rules/PropertyTest.php b/tests/feature/Rules/PropertyTest.php new file mode 100644 index 000000000..87ec97623 --- /dev/null +++ b/tests/feature/Rules/PropertyTest.php @@ -0,0 +1,106 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Missing property', expectAll( + static fn() => v::property('foo', v::intType())->assert(new stdClass()), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('Default', expectAll( + static fn() => v::property('foo', v::intType())->assert((object) ['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('Inverted', expectAll( + static fn() => v::not(v::property('foo', v::intType()))->assert((object) ['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('Double-inverted with missing property', expectAll( + static fn() => v::not(v::not(v::property('foo', v::intType())))->assert(new stdClass()), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('With wrapped name, missing property', expectAll( + static fn() => v::property('foo', v::intType()->setName('Wrapped'))->setName('Wrapper')->assert(new stdClass()), + 'Wrapped must be present', + '- Wrapped must be present', + ['foo' => 'Wrapped must be present',] +)); + +test('With wrapped name, default', expectAll( + static fn() => v::property('foo', v::intType()->setName('Wrapped'))->setName('Wrapper')->assert((object) ['foo' => 'string']), + 'Wrapped must be an integer', + '- Wrapped must be an integer', + ['foo' => 'Wrapped must be an integer',] +)); + +test('With wrapped name, inverted', expectAll( + static fn() => v::not( + v::property('foo', v::intType()->setName('Wrapped'))->setName('Wrapper') + ) + ->setName('Not') + ->assert((object) ['foo' => 12]), + 'Wrapped must not be an integer', + '- Wrapped must not be an integer', + ['foo' => 'Wrapped must not be an integer',] +)); + +test('With wrapper name, default', expectAll( + static fn() => v::property('foo', v::intType())->setName('Wrapper')->assert((object) ['foo' => 'string']), + 'foo must be an integer', + '- foo must be an integer', + ['foo' => 'foo must be an integer',] +)); + +test('With wrapper name, missing property', expectAll( + static fn() => v::property('foo', v::intType())->setName('Wrapper')->assert(new stdClass()), + 'foo must be present', + '- foo must be present', + ['foo' => 'foo must be present',] +)); + +test('With wrapper name, inverted', expectAll( + static fn() => v::not(v::property('foo', v::intType())->setName('Wrapper'))->setName('Not') + ->assert((object) ['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With "Not" name, inverted', expectAll( + static fn() => v::not(v::property('foo', v::intType()))->setName('Not')->assert((object) ['foo' => 12]), + 'foo must not be an integer', + '- foo must not be an integer', + ['foo' => 'foo must not be an integer',] +)); + +test('With template, default', expectAll( + static fn() => v::property('foo', v::intType()) + ->assert((object) ['foo' => 'string'], 'Particularly precautions perplexing property'), + 'Particularly precautions perplexing property', + '- Particularly precautions perplexing property', + ['foo' => 'Particularly precautions perplexing property',] +)); + +test('With template, inverted', expectAll( + static fn() => v::not(v::property('foo', v::intType())) + ->assert((object) ['foo' => 12], 'Not a prompt prospect of a particularly primitive property'), + 'Not a prompt prospect of a particularly primitive property', + '- Not a prompt prospect of a particularly primitive property', + ['foo' => 'Not a prompt prospect of a particularly primitive property',] +)); diff --git a/tests/feature/Rules/PunctTest.php b/tests/feature/Rules/PunctTest.php new file mode 100644 index 000000000..9adf3bf83 --- /dev/null +++ b/tests/feature/Rules/PunctTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::punct()->assert('a'), + '"a" must contain only punctuation characters', +)); + +test('Scenario #2', expectMessage( + static fn() => v::punct('c')->assert('b'), + '"b" must contain only punctuation characters and "c"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::punct())->assert('.'), + '"." must not contain punctuation characters', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::punct('d'))->assert('?'), + '"?" must not contain punctuation characters or "d"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::punct()->assert('e'), + '- "e" must contain only punctuation characters', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::punct('f')->assert('g'), + '- "g" must contain only punctuation characters and "f"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::punct())->assert('!'), + '- "!" must not contain punctuation characters', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::punct('h'))->assert(';'), + '- ";" must not contain punctuation characters or "h"', +)); diff --git a/tests/feature/Rules/ReadableTest.php b/tests/feature/Rules/ReadableTest.php new file mode 100644 index 000000000..96749176f --- /dev/null +++ b/tests/feature/Rules/ReadableTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::readable()->assert('tests/fixtures/invalid-image.jpg'), + '"tests/fixtures/invalid-image.jpg" must be readable', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::readable())->assert('tests/fixtures/valid-image.png'), + '"tests/fixtures/valid-image.png" must not be readable', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::readable()->assert(new stdClass()), + '- `stdClass {}` must be readable', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::readable())->assert('tests/fixtures/valid-image.png'), + '- "tests/fixtures/valid-image.png" must not be readable', +)); diff --git a/tests/feature/Rules/RegexTest.php b/tests/feature/Rules/RegexTest.php new file mode 100644 index 000000000..ef7360ec9 --- /dev/null +++ b/tests/feature/Rules/RegexTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::regex('/^w+$/')->assert('w poiur'), + '"w poiur" must match the pattern `/^w+$/`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::regex('/^[a-z]+$/'))->assert('wpoiur'), + '"wpoiur" must not match the pattern `/^[a-z]+$/`', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::regex('/^w+$/')->assert(new stdClass()), + '- `stdClass {}` must match the pattern `/^w+$/`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::regex('/^[a-z]+$/i'))->assert('wPoiur'), + '- "wPoiur" must not match the pattern `/^[a-z]+$/i`', +)); diff --git a/tests/feature/Rules/ResourceTypeTest.php b/tests/feature/Rules/ResourceTypeTest.php new file mode 100644 index 000000000..a48ce2f07 --- /dev/null +++ b/tests/feature/Rules/ResourceTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::resourceType()->assert('test'), + '`test(?string $description = null, ?Closure $closure = null): Pest\\Support\\HigherOrderTapProxy|Pest\\PendingCalls\\Te ...` must be a resource', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::resourceType())->assert(tmpfile()), + '`resource ` must not be a resource', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::resourceType()->assert([]), + '- `[]` must be a resource', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::resourceType())->assert(tmpfile()), + '- `resource ` must not be a resource', +)); diff --git a/tests/feature/Rules/RomanTest.php b/tests/feature/Rules/RomanTest.php new file mode 100644 index 000000000..3f1191b8f --- /dev/null +++ b/tests/feature/Rules/RomanTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::roman()->assert(1234), + '1234 must be a valid Roman numeral', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::roman())->assert('XL'), + '"XL" must not be a valid Roman numeral', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::roman()->assert('e2'), + '- "e2" must be a valid Roman numeral', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::roman())->assert('IV'), + '- "IV" must not be a valid Roman numeral', +)); diff --git a/tests/feature/Rules/ScalarValTest.php b/tests/feature/Rules/ScalarValTest.php new file mode 100644 index 000000000..3534014d0 --- /dev/null +++ b/tests/feature/Rules/ScalarValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::scalarVal()->assert([]), + '`[]` must be a scalar value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::scalarVal())->assert(true), + '`true` must not be a scalar value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::scalarVal()->assert(new stdClass()), + '- `stdClass {}` must be a scalar value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::scalarVal())->assert(42), + '- 42 must not be a scalar value', +)); diff --git a/tests/feature/Rules/SizeTest.php b/tests/feature/Rules/SizeTest.php new file mode 100644 index 000000000..65b165b08 --- /dev/null +++ b/tests/feature/Rules/SizeTest.php @@ -0,0 +1,68 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::size('1kb', '2kb')->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must be between "1kb" and "2kb"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::size('700kb', null)->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must be greater than "700kb"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::size(null, '1kb')->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must be lower than "1kb"', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::size('500kb', '600kb'))->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must not be between "500kb" and "600kb"', +)); + +test('Scenario #5', expectMessage( + static fn() => v::not(v::size('500kb', null))->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must not be greater than "500kb"', +)); + +test('Scenario #6', expectMessage( + static fn() => v::not(v::size(null, '600kb'))->assert('tests/fixtures/valid-image.gif'), + '"tests/fixtures/valid-image.gif" must not be lower than "600kb"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::size('1kb', '2kb')->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must be between "1kb" and "2kb"', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::size('700kb', null)->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must be greater than "700kb"', +)); + +test('Scenario #9', expectFullMessage( + static fn() => v::size(null, '1kb')->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must be lower than "1kb"', +)); + +test('Scenario #10', expectFullMessage( + static fn() => v::not(v::size('500kb', '600kb'))->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must not be between "500kb" and "600kb"', +)); + +test('Scenario #11', expectFullMessage( + static fn() => v::not(v::size('500kb', null))->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must not be greater than "500kb"', +)); + +test('Scenario #12', expectFullMessage( + static fn() => v::not(v::size(null, '600kb'))->assert('tests/fixtures/valid-image.gif'), + '- "tests/fixtures/valid-image.gif" must not be lower than "600kb"', +)); diff --git a/tests/feature/Rules/SlugTest.php b/tests/feature/Rules/SlugTest.php new file mode 100644 index 000000000..2b250b155 --- /dev/null +++ b/tests/feature/Rules/SlugTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::slug()->assert('my-Slug'), + '"my-Slug" must be a valid slug', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::slug())->assert('my-slug'), + '"my-slug" must not be a valid slug', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::slug()->assert('my-Slug'), + '- "my-Slug" must be a valid slug', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::slug())->assert('my-slug'), + '- "my-slug" must not be a valid slug', +)); diff --git a/tests/feature/Rules/SortedTest.php b/tests/feature/Rules/SortedTest.php new file mode 100644 index 000000000..d0f4051db --- /dev/null +++ b/tests/feature/Rules/SortedTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::sorted('ASC')->assert([1, 3, 2]), + '`[1, 3, 2]` must be sorted in ascending order', +)); + +test('Scenario #2', expectMessage( + static fn() => v::sorted('DESC')->assert([1, 2, 3]), + '`[1, 2, 3]` must be sorted in descending order', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::sorted('ASC'))->assert([1, 2, 3]), + '`[1, 2, 3]` must not be sorted in ascending order', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::sorted('DESC'))->assert([3, 2, 1]), + '`[3, 2, 1]` must not be sorted in descending order', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::sorted('ASC')->assert([3, 2, 1]), + '- `[3, 2, 1]` must be sorted in ascending order', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::sorted('DESC')->assert([1, 2, 3]), + '- `[1, 2, 3]` must be sorted in descending order', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::sorted('ASC'))->assert([1, 2, 3]), + '- `[1, 2, 3]` must not be sorted in ascending order', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::sorted('DESC'))->assert([3, 2, 1]), + '- `[3, 2, 1]` must not be sorted in descending order', +)); diff --git a/tests/feature/Rules/SpaceTest.php b/tests/feature/Rules/SpaceTest.php new file mode 100644 index 000000000..d77af962d --- /dev/null +++ b/tests/feature/Rules/SpaceTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::space()->assert('ab'), + '"ab" must contain only space characters', +)); + +test('Scenario #2', expectMessage( + static fn() => v::space('c')->assert('cd'), + '"cd" must contain only space characters and "c"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::space())->assert("\t"), + '"\\t" must not contain space characters', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::space('def'))->assert("\r"), + '"\\r" must not contain space characters or "def"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::space()->assert('ef'), + '- "ef" must contain only space characters', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::space('e')->assert('gh'), + '- "gh" must contain only space characters and "e"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::space())->assert("\n"), + '- "\\n" must not contain space characters', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::space('yk'))->assert(' k'), + '- " k" must not contain space characters or "yk"', +)); diff --git a/tests/feature/Rules/StartsWithTest.php b/tests/feature/Rules/StartsWithTest.php new file mode 100644 index 000000000..712f4829c --- /dev/null +++ b/tests/feature/Rules/StartsWithTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::startsWith('b')->assert(['a', 'b']), + '`["a", "b"]` must start with "b"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::startsWith(1.1))->assert([1.1, 2.2]), + '`[1.1, 2.2]` must not start with 1.1', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::startsWith('3.3', true)->assert([3.3, 4.4]), + '- `[3.3, 4.4]` must start with "3.3"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::startsWith('c'))->assert(['c', 'd']), + '- `["c", "d"]` must not start with "c"', +)); diff --git a/tests/feature/Rules/StringTypeTest.php b/tests/feature/Rules/StringTypeTest.php new file mode 100644 index 000000000..fb41c26e4 --- /dev/null +++ b/tests/feature/Rules/StringTypeTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::stringType()->assert(42), + '42 must be a string', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::stringType())->assert('foo'), + '"foo" must not be a string', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::stringType()->assert(true), + '- `true` must be a string', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::stringType())->assert('bar'), + '- "bar" must not be a string', +)); diff --git a/tests/feature/Rules/StringValTest.php b/tests/feature/Rules/StringValTest.php new file mode 100644 index 000000000..d89f407f3 --- /dev/null +++ b/tests/feature/Rules/StringValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::stringVal()->assert([]), + '`[]` must be a string value', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::stringVal())->assert(true), + '`true` must not be a string value', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::stringVal()->assert(new stdClass()), + '- `stdClass {}` must be a string value', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::stringVal())->assert(42), + '- 42 must not be a string value', +)); diff --git a/tests/feature/Rules/SubsetTest.php b/tests/feature/Rules/SubsetTest.php new file mode 100644 index 000000000..f8d29418f --- /dev/null +++ b/tests/feature/Rules/SubsetTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::subset([1, 2])->assert([1, 2, 3]), + '`[1, 2, 3]` must be subset of `[1, 2]`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::subset([1, 2, 3]))->assert([1, 2]), + '`[1, 2]` must not be subset of `[1, 2, 3]`', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::subset(['A', 'B'])->assert(['B', 'C']), + '- `["B", "C"]` must be subset of `["A", "B"]`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::subset(['A']))->assert(['A']), + '- `["A"]` must not be subset of `["A"]`', +)); diff --git a/tests/feature/Rules/SymbolicLinkTest.php b/tests/feature/Rules/SymbolicLinkTest.php new file mode 100644 index 000000000..2066fc8f7 --- /dev/null +++ b/tests/feature/Rules/SymbolicLinkTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::symbolicLink()->assert('tests/fixtures/fake-filename'), + '"tests/fixtures/fake-filename" must be a symbolic link', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::symbolicLink())->assert('tests/fixtures/symbolic-link'), + '"tests/fixtures/symbolic-link" must not be a symbolic link', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::symbolicLink()->assert('tests/fixtures/fake-filename'), + '- "tests/fixtures/fake-filename" must be a symbolic link', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::symbolicLink())->assert('tests/fixtures/symbolic-link'), + '- "tests/fixtures/symbolic-link" must not be a symbolic link', +)); diff --git a/tests/feature/Rules/TimeTest.php b/tests/feature/Rules/TimeTest.php new file mode 100644 index 000000000..06cdefd35 --- /dev/null +++ b/tests/feature/Rules/TimeTest.php @@ -0,0 +1,30 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + +test('Scenario #1', expectMessage( + static fn() => v::time()->assert('2018-01-30'), + '"2018-01-30" must be a valid time in the format "23:59:59"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::time())->assert('09:25:46'), + '"09:25:46" must not be a valid time in the format "23:59:59"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::time()->assert('2018-01-30'), + '- "2018-01-30" must be a valid time in the format "23:59:59"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::time('g:i A'))->assert('8:13 AM'), + '- "8:13 AM" must not be a valid time in the format "11:59 PM"', +)); diff --git a/tests/feature/Rules/TldTest.php b/tests/feature/Rules/TldTest.php new file mode 100644 index 000000000..851a157fb --- /dev/null +++ b/tests/feature/Rules/TldTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::tld()->assert('42'), + '"42" must be a valid top-level domain name', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::tld())->assert('com'), + '"com" must not be a valid top-level domain name', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::tld()->assert('1984'), + '- "1984" must be a valid top-level domain name', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::tld())->assert('com'), + '- "com" must not be a valid top-level domain name', +)); diff --git a/tests/feature/Rules/TrueValTest.php b/tests/feature/Rules/TrueValTest.php new file mode 100644 index 000000000..4cb295368 --- /dev/null +++ b/tests/feature/Rules/TrueValTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::trueVal()->assert(false), + '`false` must evaluate to `true`', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::trueVal())->assert(1), + '1 must not evaluate to `true`', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::trueVal()->assert(0), + '- 0 must evaluate to `true`', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::trueVal())->assert('true'), + '- "true" must not evaluate to `true`', +)); diff --git a/tests/feature/Rules/UndefOrTest.php b/tests/feature/Rules/UndefOrTest.php new file mode 100644 index 000000000..f14468800 --- /dev/null +++ b/tests/feature/Rules/UndefOrTest.php @@ -0,0 +1,111 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Default', expectAll( + static fn() => v::undefOr(v::alpha())->assert(1234), + '1234 must contain only letters (a-z) or must be undefined', + '- 1234 must contain only letters (a-z) or must be undefined', + ['undefOrAlpha' => '1234 must contain only letters (a-z) or must be undefined',] +)); + +test('Inverted wrapper', expectAll( + static fn() => v::not(v::undefOr(v::alpha()))->assert('alpha'), + '"alpha" must not contain letters (a-z) and must not be undefined', + '- "alpha" must not contain letters (a-z) and must not be undefined', + ['notUndefOrAlpha' => '"alpha" must not contain letters (a-z) and must not be undefined',] +)); + +test('Inverted wrapped', expectAll( + static fn() => v::undefOr(v::not(v::alpha()))->assert('alpha'), + '"alpha" must not contain letters (a-z) or must be undefined', + '- "alpha" must not contain letters (a-z) or must be undefined', + ['undefOrNotAlpha' => '"alpha" must not contain letters (a-z) or must be undefined',] +)); + +test('Inverted undefined', expectAll( + static fn() => v::not(v::undefOr(v::alpha()))->assert(null), + '`null` must not contain letters (a-z) and must not be undefined', + '- `null` must not contain letters (a-z) and must not be undefined', + ['notUndefOrAlpha' => '`null` must not contain letters (a-z) and must not be undefined',] +)); + +test('Inverted undefined, wrapped name', expectAll( + static fn() => v::not(v::undefOr(v::alpha()->setName('Wrapped')))->assert(null), + 'Wrapped must not contain letters (a-z) and must not be undefined', + '- Wrapped must not contain letters (a-z) and must not be undefined', + ['notUndefOrAlpha' => 'Wrapped must not contain letters (a-z) and must not be undefined',] +)); + +test('Inverted undefined, wrapper name', expectAll( + static fn() => v::not(v::undefOr(v::alpha())->setName('Wrapper'))->assert(null), + 'Wrapper must not contain letters (a-z) and must not be undefined', + '- Wrapper must not contain letters (a-z) and must not be undefined', + ['notUndefOrAlpha' => 'Wrapper must not contain letters (a-z) and must not be undefined',] +)); + +test('Inverted undefined, not name', expectAll( + static fn() => v::not(v::undefOr(v::alpha()))->setName('Not')->assert(null), + 'Not must not contain letters (a-z) and must not be undefined', + '- Not must not contain letters (a-z) and must not be undefined', + ['notUndefOrAlpha' => 'Not must not contain letters (a-z) and must not be undefined',] +)); + +test('With template', expectAll( + static fn() => v::undefOr(v::alpha())->assert(123, 'Underneath the undulating umbrella'), + 'Underneath the undulating umbrella', + '- Underneath the undulating umbrella', + ['undefOrAlpha' => 'Underneath the undulating umbrella',] +)); + +test('With array template', expectAll( + static fn() => v::undefOr(v::alpha())->assert(123, ['undefOrAlpha' => 'Undefined number of unique unicorns']), + 'Undefined number of unique unicorns', + '- Undefined number of unique unicorns', + ['undefOrAlpha' => 'Undefined number of unique unicorns',] +)); + +test('Inverted undefined with template', expectAll( + static fn() => v::not(v::undefOr(v::alpha()))->assert('', ['notUndefOrAlpha' => 'Should not be undefined or alpha']), + 'Should not be undefined or alpha', + '- Should not be undefined or alpha', + ['notUndefOrAlpha' => 'Should not be undefined or alpha',] +)); + +test('Without subsequent result', expectAll( + static fn() => v::undefOr(v::alpha()->stringType())->assert(1234), + '1234 must contain only letters (a-z) or must be undefined', + <<<'MESSAGE' + - All of the required rules must pass for 1234 + - 1234 must contain only letters (a-z) or must be undefined + - 1234 must be a string or must be undefined + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1234', + 'undefOrAlpha' => '1234 must contain only letters (a-z) or must be undefined', + 'undefOrStringType' => '1234 must be a string or must be undefined', + ] +)); + +test('Without subsequent result with templates', expectAll( + static fn() => v::undefOr(v::alpha()->stringType())->assert(1234, [ + 'undefOrAlpha' => 'Should be nul or alpha', + 'undefOrStringType' => 'Should be nul or string type', + ]), + 'Should be nul or alpha', + <<<'MESSAGE' + - All of the required rules must pass for 1234 + - Should be nul or alpha + - Should be nul or string type + MESSAGE, + [ + '__root__' => 'All of the required rules must pass for 1234', + 'undefOrAlpha' => 'Should be nul or alpha', + 'undefOrStringType' => 'Should be nul or string type', + ] +)); diff --git a/tests/feature/Rules/UniqueTest.php b/tests/feature/Rules/UniqueTest.php new file mode 100644 index 000000000..4cc31e34d --- /dev/null +++ b/tests/feature/Rules/UniqueTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::unique()->assert([1, 2, 2, 3]), + '`[1, 2, 2, 3]` must not contain duplicates', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::unique())->assert([1, 2, 3, 4]), + '`[1, 2, 3, 4]` must contain duplicates', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::unique()->assert('test'), + '- `test(?string $description = null, ?Closure $closure = null): Pest\\Support\\HigherOrderTapProxy|Pest\\PendingCalls\\Te ...` must not contain duplicates', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::unique())->assert(['a', 'b', 'c']), + '- `["a", "b", "c"]` must contain duplicates', +)); diff --git a/tests/feature/Rules/UploadedTest.php b/tests/feature/Rules/UploadedTest.php new file mode 100644 index 000000000..23e3d6fb6 --- /dev/null +++ b/tests/feature/Rules/UploadedTest.php @@ -0,0 +1,40 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static function (): void { + uopz_set_return('is_uploaded_file', false); + v::uploaded()->assert('filename'); + }, + '"filename" must be an uploaded file', +))->skip(extension_loaded('uopz') == false, 'Extension "uopz" is required to test "Uploaded" rule'); + +test('Scenario #2', expectMessage( + static function (): void { + uopz_set_return('is_uploaded_file', true); + v::not(v::uploaded())->assert('filename'); + }, + '"filename" must not be an uploaded file', +))->skip(extension_loaded('uopz') == false, 'Extension "uopz" is required to test "Uploaded" rule'); + +test('Scenario #3', expectFullMessage( + static function (): void { + uopz_set_return('is_uploaded_file', false); + v::uploaded()->assert('filename'); + }, + '- "filename" must be an uploaded file', +))->skip(extension_loaded('uopz') == false, 'Extension "uopz" is required to test "Uploaded" rule'); + +test('Scenario #4', expectFullMessage( + static function (): void { + uopz_set_return('is_uploaded_file', true); + v::not(v::uploaded())->assert('filename'); + }, + '- "filename" must not be an uploaded file', +))->skip(extension_loaded('uopz') == false, 'Extension "uopz" is required to test "Uploaded" rule'); diff --git a/tests/feature/Rules/UppercaseTest.php b/tests/feature/Rules/UppercaseTest.php new file mode 100644 index 000000000..92961a3ad --- /dev/null +++ b/tests/feature/Rules/UppercaseTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::uppercase()->assert('lowercase'), + '"lowercase" must contain only uppercase letters', +)); + +test('Scenario #2', expectFullMessage( + static fn() => v::uppercase()->assert('lowercase'), + '- "lowercase" must contain only uppercase letters', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::uppercase())->assert('UPPERCASE'), + '"UPPERCASE" must not contain only uppercase letters', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::uppercase())->assert('UPPERCASE'), + '- "UPPERCASE" must not contain only uppercase letters', +)); diff --git a/tests/feature/Rules/UrlTest.php b/tests/feature/Rules/UrlTest.php new file mode 100644 index 000000000..67de5f8d3 --- /dev/null +++ b/tests/feature/Rules/UrlTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::url()->assert('example.com'), + '"example.com" must be a URL', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::url())->assert('http://example.com'), + '"http://example.com" must not be a URL', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::url()->assert('example.com'), + '- "example.com" must be a URL', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::url())->assert('http://example.com'), + '- "http://example.com" must not be a URL', +)); diff --git a/tests/feature/Rules/UuidTest.php b/tests/feature/Rules/UuidTest.php new file mode 100644 index 000000000..b8b6a7342 --- /dev/null +++ b/tests/feature/Rules/UuidTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::uuid()->assert('g71a18f4-3a13-11e7-a919-92ebcb67fe33'), + '"g71a18f4-3a13-11e7-a919-92ebcb67fe33" must be a valid UUID', +)); + +test('Scenario #2', expectMessage( + static fn() => v::uuid(1)->assert('e0b5ffb9-9caf-2a34-9673-8fc91db78be6'), + '"e0b5ffb9-9caf-2a34-9673-8fc91db78be6" must be a valid UUID version 1', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::uuid())->assert('fb3a7909-8034-59f5-8f38-21adbc168db7'), + '"fb3a7909-8034-59f5-8f38-21adbc168db7" must not be a valid UUID', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::uuid(3))->assert('11a38b9a-b3da-360f-9353-a5a725514269'), + '"11a38b9a-b3da-360f-9353-a5a725514269" must not be a valid UUID version 3', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::uuid()->assert('g71a18f4-3a13-11e7-a919-92ebcb67fe33'), + '- "g71a18f4-3a13-11e7-a919-92ebcb67fe33" must be a valid UUID', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::uuid(4)->assert('a71a18f4-3a13-11e7-a919-92ebcb67fe33'), + '- "a71a18f4-3a13-11e7-a919-92ebcb67fe33" must be a valid UUID version 4', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::uuid())->assert('e0b5ffb9-9caf-4a34-9673-8fc91db78be6'), + '- "e0b5ffb9-9caf-4a34-9673-8fc91db78be6" must not be a valid UUID', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::uuid(5))->assert('c4a760a8-dbcf-5254-a0d9-6a4474bd1b62'), + '- "c4a760a8-dbcf-5254-a0d9-6a4474bd1b62" must not be a valid UUID version 5', +)); diff --git a/tests/feature/Rules/VersionTest.php b/tests/feature/Rules/VersionTest.php new file mode 100644 index 000000000..6fcbd9956 --- /dev/null +++ b/tests/feature/Rules/VersionTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::version()->assert('1.3.7--'), + '"1.3.7--" must be a version', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::version())->assert('1.0.0-alpha'), + '"1.0.0-alpha" must not be a version', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::version()->assert('1.2.3.4-beta'), + '- "1.2.3.4-beta" must be a version', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::version())->assert('1.3.7-rc.1'), + '- "1.3.7-rc.1" must not be a version', +)); diff --git a/tests/feature/Rules/VideoUrlTest.php b/tests/feature/Rules/VideoUrlTest.php new file mode 100644 index 000000000..6b031d2dc --- /dev/null +++ b/tests/feature/Rules/VideoUrlTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::videoUrl()->assert('example.com'), + '"example.com" must be a valid video URL', +)); + +test('Scenario #2', expectMessage( + static fn() => v::videoUrl('YouTube')->assert('example.com'), + '"example.com" must be a valid YouTube video URL', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::videoUrl())->assert('https://player.vimeo.com/video/7178746722'), + '"https://player.vimeo.com/video/7178746722" must not be a valid video URL', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::videoUrl('YouTube'))->assert('https://www.youtube.com/embed/netHLn9TScY'), + '"https://www.youtube.com/embed/netHLn9TScY" must not be a valid YouTube video URL', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::videoUrl()->assert('example.com'), + '- "example.com" must be a valid video URL', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::videoUrl('Vimeo')->assert('example.com'), + '- "example.com" must be a valid Vimeo video URL', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::videoUrl())->assert('https://youtu.be/netHLn9TScY'), + '- "https://youtu.be/netHLn9TScY" must not be a valid video URL', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::videoUrl('Vimeo'))->assert('https://vimeo.com/71787467'), + '- "https://vimeo.com/71787467" must not be a valid Vimeo video URL', +)); diff --git a/tests/feature/Rules/VowelTest.php b/tests/feature/Rules/VowelTest.php new file mode 100644 index 000000000..ca2c249a6 --- /dev/null +++ b/tests/feature/Rules/VowelTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::vowel()->assert('b'), + '"b" must consist of vowels only', +)); + +test('Scenario #2', expectMessage( + static fn() => v::vowel('c')->assert('d'), + '"d" must consist of vowels and "c"', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::vowel())->assert('a'), + '"a" must not consist of vowels only', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::vowel('f'))->assert('e'), + '"e" must not consist of vowels or "f"', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::vowel()->assert('g'), + '- "g" must consist of vowels only', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::vowel('h')->assert('j'), + '- "j" must consist of vowels and "h"', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::not(v::vowel())->assert('i'), + '- "i" must not consist of vowels only', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::vowel('k'))->assert('o'), + '- "o" must not consist of vowels or "k"', +)); diff --git a/tests/feature/Rules/WhenTest.php b/tests/feature/Rules/WhenTest.php new file mode 100644 index 000000000..9945996d8 --- /dev/null +++ b/tests/feature/Rules/WhenTest.php @@ -0,0 +1,56 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('When valid use "then"', expectAll( + static fn() => v::when(v::intVal(), v::positive(), v::notEmpty())->assert(-1), + '-1 must be a positive number', + '- -1 must be a positive number', + ['positive' => '-1 must be a positive number',] +)); + +test('When invalid use "else"', expectAll( + static fn() => v::when(v::intVal(), v::positive(), v::notEmpty())->assert(''), + 'The value must not be empty', + '- The value must not be empty', + ['notEmpty' => 'The value must not be empty',] +)); + +test('When valid use "then" using single template', expectAll( + static fn() => v::when(v::intVal(), v::positive(), v::notEmpty())->assert(-1, 'That did not go as planned'), + 'That did not go as planned', + '- That did not go as planned', + ['positive' => 'That did not go as planned',] +)); + +test('When invalid use "else" using single template', expectAll( + static fn() => v::when(v::intVal(), v::positive(), v::notEmpty())->assert('', 'That could have been better'), + 'That could have been better', + '- That could have been better', + ['notEmpty' => 'That could have been better',] +)); + +test('When valid use "then" using array template', expectAll( + static fn() => v::when(v::intVal(), v::positive(), v::notEmpty())->assert(-1, [ + 'notEmpty' => '--Never shown--', + 'positive' => 'Not positive', + ]), + 'Not positive', + '- Not positive', + ['positive' => 'Not positive',] +)); + +test('When invalid use "else" using array template', expectAll( + static fn() => v::when(v::intVal(), v::positive(), v::notEmpty())->assert('', [ + 'notEmpty' => 'Not empty', + 'positive' => '--Never shown--', + ]), + 'Not empty', + '- Not empty', + ['notEmpty' => 'Not empty',] +)); diff --git a/tests/feature/Rules/WritableTest.php b/tests/feature/Rules/WritableTest.php new file mode 100644 index 000000000..9caaf0e61 --- /dev/null +++ b/tests/feature/Rules/WritableTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::writable()->assert('/path/of/a/valid/writable/file.txt'), + '"/path/of/a/valid/writable/file.txt" must be writable', +)); + +test('Scenario #2', expectMessage( + static fn() => v::not(v::writable())->assert('tests/fixtures/valid-image.png'), + '"tests/fixtures/valid-image.png" must not be writable', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::writable()->assert([]), + '- `[]` must be writable', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::not(v::writable())->assert('tests/fixtures/invalid-image.png'), + '- "tests/fixtures/invalid-image.png" must not be writable', +)); diff --git a/tests/feature/Rules/XdigitTest.php b/tests/feature/Rules/XdigitTest.php new file mode 100644 index 000000000..7e9c61b9d --- /dev/null +++ b/tests/feature/Rules/XdigitTest.php @@ -0,0 +1,48 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::xdigit()->assert('aaa%a'), + '"aaa%a" must only contain hexadecimal digits', +)); + +test('Scenario #2', expectMessage( + static fn() => v::xdigit(' ')->assert('bbb%b'), + '"bbb%b" must contain hexadecimal digits and " "', +)); + +test('Scenario #3', expectMessage( + static fn() => v::not(v::xdigit())->assert('ccccc'), + '"ccccc" must not only contain hexadecimal digits', +)); + +test('Scenario #4', expectMessage( + static fn() => v::not(v::xdigit('% '))->assert('ddd%d'), + '"ddd%d" must not contain hexadecimal digits or "% "', +)); + +test('Scenario #5', expectFullMessage( + static fn() => v::xdigit()->assert('eee^e'), + '- "eee^e" must only contain hexadecimal digits', +)); + +test('Scenario #6', expectFullMessage( + static fn() => v::not(v::xdigit())->assert('fffff'), + '- "fffff" must not only contain hexadecimal digits', +)); + +test('Scenario #7', expectFullMessage( + static fn() => v::xdigit('* &%')->assert('000^0'), + '- "000^0" must contain hexadecimal digits and "* &%"', +)); + +test('Scenario #8', expectFullMessage( + static fn() => v::not(v::xdigit('^'))->assert('111^1'), + '- "111^1" must not contain hexadecimal digits or "^"', +)); diff --git a/tests/feature/Rules/YesTest.php b/tests/feature/Rules/YesTest.php new file mode 100644 index 000000000..4074c24a8 --- /dev/null +++ b/tests/feature/Rules/YesTest.php @@ -0,0 +1,28 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessage( + static fn() => v::not(v::yes())->assert('Yes'), + '"Yes" must not be similar to "Yes"', +)); + +test('Scenario #2', expectMessage( + static fn() => v::yes()->assert('si'), + '"si" must be similar to "Yes"', +)); + +test('Scenario #3', expectFullMessage( + static fn() => v::not(v::yes())->assert('Yes'), + '- "Yes" must not be similar to "Yes"', +)); + +test('Scenario #4', expectFullMessage( + static fn() => v::yes()->assert('si'), + '- "si" must be similar to "Yes"', +)); diff --git a/tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsFullMessage.php b/tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsFullMessage.php new file mode 100644 index 000000000..9a59e4d8e --- /dev/null +++ b/tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsFullMessage.php @@ -0,0 +1,17 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +test('Scenario #1', expectFullMessage( + static function (): void { + Validator::callback('is_string')->between(1, 2)->setTemplate('{{name}} is not tasty')->assert('something'); + }, + '- "something" is not tasty', +)); diff --git a/tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsMainMessage.php b/tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsMainMessage.php new file mode 100644 index 000000000..43addbfcc --- /dev/null +++ b/tests/feature/SetTemplateWithMultipleValidatorsShouldUseTemplateAsMainMessage.php @@ -0,0 +1,17 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +test('Scenario #1', expectMessage( + static function (): void { + Validator::callback('is_int')->between(1, 2)->setTemplate('{{name}} is not tasty')->assert('something'); + }, + '"something" is not tasty', +)); diff --git a/tests/feature/SetTemplateWithSingleValidatorShouldUseTemplateAsMainMessage.php b/tests/feature/SetTemplateWithSingleValidatorShouldUseTemplateAsMainMessage.php new file mode 100644 index 000000000..bbcc2d248 --- /dev/null +++ b/tests/feature/SetTemplateWithSingleValidatorShouldUseTemplateAsMainMessage.php @@ -0,0 +1,22 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +use Respect\Validation\Validator; + +$rule = Validator::callback('is_int')->setTemplate('{{name}} is not tasty'); + +test('Scenario #1', expectMessage( + static fn() => $rule->assert('something'), + '"something" is not tasty', +)); + +test('Scenario #2', expectMessage( + static fn() => $rule->assert('something'), + '"something" is not tasty', +)); diff --git a/tests/feature/ShouldNotOverwriteDefinedNames.php b/tests/feature/ShouldNotOverwriteDefinedNames.php new file mode 100644 index 000000000..6ec196e0b --- /dev/null +++ b/tests/feature/ShouldNotOverwriteDefinedNames.php @@ -0,0 +1,25 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$input = ['email' => 'not an email']; + +test('Scenario #1', expectMessage( + static fn() => v::key('email', v::email()->setName('Email'))->setName('Foo')->assert($input), + 'Email must be a valid email address', +)); + +test('Scenario #2', expectMessage( + static fn() => v::key('email', v::email())->setName('Email')->assert($input), + 'email must be a valid email address', +)); + +test('Scenario #3', expectMessage( + static fn() => v::key('email', v::email())->assert($input), + 'email must be a valid email address', +)); diff --git a/tests/feature/Transformers/AliasesTest.php b/tests/feature/Transformers/AliasesTest.php new file mode 100644 index 000000000..ffc620c75 --- /dev/null +++ b/tests/feature/Transformers/AliasesTest.php @@ -0,0 +1,17 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + +test('Optional', expectAll( + static fn() => v::optional(v::scalarVal())->assert([]), + '`[]` must be a scalar value or must be undefined', + '- `[]` must be a scalar value or must be undefined', + ['undefOrScalarVal' => '`[]` must be a scalar value or must be undefined'] +)); diff --git a/tests/feature/Transformers/DeprecatedAgeTest.php b/tests/feature/Transformers/DeprecatedAgeTest.php new file mode 100644 index 000000000..d31278314 --- /dev/null +++ b/tests/feature/Transformers/DeprecatedAgeTest.php @@ -0,0 +1,58 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + +test('Scenario #1', expectMessageAndError( + static fn() => v::minAge(18)->assert('17 years ago'), + 'The number of years between now and 17 years ago must be greater than or equal to 18', + 'The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::not(v::minAge(18))->assert('-30 years'), + 'The number of years between now and -30 years must be less than 18', + 'The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::minAge(18)->assert('yesterday'), + 'The number of years between now and yesterday must be greater than or equal to 18', + 'The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::minAge(18, 'd/m/Y')->assert('12/10/2010'), + 'The number of years between now and 12/10/2010 must be greater than or equal to 18', + 'The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #5', expectMessageAndError( + static fn() => v::maxAge(12)->assert('50 years ago'), + 'The number of years between now and 50 years ago must be less than or equal to 12', + 'The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #6', expectMessageAndError( + static fn() => v::not(v::maxAge(12))->assert('11 years ago'), + 'The number of years between now and 11 years ago must be greater than 12', + 'The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #7', expectMessageAndError( + static fn() => v::maxAge(12, 'Y-m-d')->assert('1988-09-09'), + 'The number of years between now and 1988-09-09 must be less than or equal to 12', + 'The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); + +test('Scenario #8', expectMessageAndError( + static fn() => v::not(v::maxAge(12, 'Y-m-d'))->assert('2018-01-01'), + 'The number of years between now and 2018-01-01 must be greater than 12', + 'The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead.', +)); diff --git a/tests/feature/Transformers/DeprecatedAttributeTest.php b/tests/feature/Transformers/DeprecatedAttributeTest.php new file mode 100644 index 000000000..33ed12588 --- /dev/null +++ b/tests/feature/Transformers/DeprecatedAttributeTest.php @@ -0,0 +1,60 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$object = new stdClass(); +$object->foo = true; +$object->bar = 42; + +test('Scenario #1', expectMessageAndError( + static fn() => v::attribute('baz')->assert($object), + 'baz must be present', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use propertyExists() instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::not(v::attribute('foo'))->assert($object), + 'foo must not be present', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use propertyExists() instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::attribute('foo', v::falseVal())->assert($object), + 'foo must evaluate to `false`', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use property() instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::not(v::attribute('foo', v::trueVal()))->assert($object), + 'foo must not evaluate to `true`', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use property() instead.' +)); + +test('Scenario #5', expectMessageAndError( + static fn() => v::attribute('foo', v::falseVal(), true)->assert($object), + 'foo must evaluate to `false`', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use property() instead.' +)); + +test('Scenario #6', expectMessageAndError( + static fn() => v::not(v::attribute('foo', v::trueVal(), true))->assert($object), + 'foo must not evaluate to `true`', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use property() instead.' +)); + +test('Scenario #7', expectMessageAndError( + static fn() => v::attribute('foo', v::falseVal(), false)->assert($object), + 'foo must evaluate to `false`', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use propertyOptional() instead.' +)); + +test('Scenario #8', expectMessageAndError( + static fn() => v::not(v::attribute('foo', v::trueVal(), false))->assert($object), + 'foo must not evaluate to `true`', + 'The attribute() rule has been deprecated and will be removed in the next major version. Use propertyOptional() instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedKeyNestedTest.php b/tests/feature/Transformers/DeprecatedKeyNestedTest.php new file mode 100644 index 000000000..3c800d525 --- /dev/null +++ b/tests/feature/Transformers/DeprecatedKeyNestedTest.php @@ -0,0 +1,38 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$input = [ + 'foo' => (object) [ + 'bar' => 123, + ], +]; + +test('Scenario #1', expectMessageAndError( + static fn() => v::keyNested('foo.bar.baz')->assert(['foo.bar.baz' => false]), + 'foo must be present', + 'The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::keyNested('foo.bar', v::negative())->assert($input), + 'bar must be a negative number', + 'The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::keyNested('foo.bar', v::stringType())->assert(new ArrayObject($input)), + 'bar must be a string', + 'The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::keyNested('foo.bar', v::floatType(), false)->assert($input), + 'bar must be float', + 'The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedKeyTest.php b/tests/feature/Transformers/DeprecatedKeyTest.php new file mode 100644 index 000000000..b34c5773b --- /dev/null +++ b/tests/feature/Transformers/DeprecatedKeyTest.php @@ -0,0 +1,46 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +$array = ['foo' => true, 'bar' => 42]; + +test('Scenario #1', expectMessageAndError( + static fn() => v::key('baz')->assert($array), + 'baz must be present', + 'Calling key() without a second parameter has been deprecated, and will be not be allowed in the next major version. Use keyExists() instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::not(v::key('foo'))->assert($array), + 'foo must not be present', + 'Calling key() without a second parameter has been deprecated, and will be not be allowed in the next major version. Use keyExists() instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::key('foo', v::falseVal(), true)->assert($array), + 'foo must evaluate to `false`', + 'Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use key() without the third parameter.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::not(v::key('foo', v::trueVal(), true))->assert($array), + 'foo must not evaluate to `true`', + 'Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use key() without the third parameter.' +)); + +test('Scenario #5', expectMessageAndError( + static fn() => v::key('foo', v::falseVal(), false)->assert($array), + 'foo must evaluate to `false`', + 'Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use keyOptional() instead.' +)); + +test('Scenario #6', expectMessageAndError( + static fn() => v::not(v::key('foo', v::trueVal(), false))->assert($array), + 'foo must not evaluate to `true`', + 'Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use keyOptional() instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedKeyValueTest.php b/tests/feature/Transformers/DeprecatedKeyValueTest.php new file mode 100644 index 000000000..cea2da218 --- /dev/null +++ b/tests/feature/Transformers/DeprecatedKeyValueTest.php @@ -0,0 +1,68 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessageAndError( + static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['bar' => 42]), + 'foo must be present', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 42]), + 'bar must be present', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::keyValue('foo', 'json', 'bar')->assert(['foo' => 42, 'bar' => 43]), + 'bar must be valid to validate foo', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 1, 'bar' => 2]), + 'foo must be equal to 2', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #5', expectMessageAndError( + static fn() => v::not(v::keyValue('foo', 'equals', 'bar'))->assert(['foo' => 1, 'bar' => 1]), + 'foo must not be equal to 1', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #6', expectMessageAndError( + static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['bar' => 42]), + 'foo must be present', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #7', expectMessageAndError( + static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 42]), + 'bar must be present', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #8', expectMessageAndError( + static fn() => v::keyValue('foo', 'json', 'bar')->assert(['foo' => 42, 'bar' => 43]), + 'bar must be valid to validate foo', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #9', expectMessageAndError( + static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 1, 'bar' => 2]), + 'foo must be equal to 2', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); + +test('Scenario #10', expectMessageAndError( + static fn() => v::not(v::keyValue('foo', 'equals', 'bar'))->assert(['foo' => 1, 'bar' => 1]), + 'foo must not be equal to 1', + 'The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedLengthTest.php b/tests/feature/Transformers/DeprecatedLengthTest.php new file mode 100644 index 000000000..b6febec80 --- /dev/null +++ b/tests/feature/Transformers/DeprecatedLengthTest.php @@ -0,0 +1,154 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +require_once 'vendor/autoload.php'; + +test('Scenario #1', expectMessageAndError( + static fn() => v::length(0, 5, false)->assert('forest'), + 'The length of "forest" must be less than 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(5) instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::length(10, 20)->assert('river'), + 'The length of "river" must be between 10 and 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(10, 20) instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::length(15, null, false)->assert('mountain'), + 'The length of "mountain" must be greater than 15', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(15) instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::length(20)->assert('ocean'), + 'The length of "ocean" must be greater than or equal to 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(20) instead.' +)); + +test('Scenario #5', expectMessageAndError( + static fn() => v::length(2, 5)->assert('desert'), + 'The length of "desert" must be between 2 and 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(2, 5) instead.' +)); + +test('Scenario #6', expectMessageAndError( + static fn() => v::not(v::length(0, 15))->assert('rainforest'), + 'The length of "rainforest" must be greater than 15', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThanOrEqual(15) instead.' +)); + +test('Scenario #7', expectMessageAndError( + static fn() => v::not(v::length(0, 20, false))->assert('glacier'), + 'The length of "glacier" must not be less than 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(20) instead.' +)); + +test('Scenario #8', expectMessageAndError( + static fn() => v::not(v::length(3, null))->assert('meadow'), + 'The length of "meadow" must be less than 3', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(3) instead.' +)); + +test('Scenario #9', expectMessageAndError( + static fn() => v::not(v::length(5, null, false))->assert('volcano'), + 'The length of "volcano" must not be greater than 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(5) instead.' +)); + +test('Scenario #10', expectMessageAndError( + static fn() => v::not(v::length(5, 20))->assert('canyon'), + 'The length of "canyon" must not be between 5 and 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(5, 20) instead.' +)); + +test('Scenario #11', expectMessageAndError( + static fn() => v::length(0, 5, false)->assert('prairie'), + 'The length of "prairie" must be less than 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(5) instead.' +)); + +test('Scenario #12', expectMessageAndError( + static fn() => v::length(0, 5)->assert('wetland'), + 'The length of "wetland" must be less than or equal to 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThanOrEqual(5) instead.' +)); + +test('Scenario #13', expectMessageAndError( + static fn() => v::length(15, null, false)->assert('tundra'), + 'The length of "tundra" must be greater than 15', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(15) instead.' +)); + +test('Scenario #14', expectMessageAndError( + static fn() => v::length(20)->assert('savanna'), + 'The length of "savanna" must be greater than or equal to 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(20) instead.' +)); + +test('Scenario #15', expectMessageAndError( + static fn() => v::length(7, 10)->assert('marsh'), + 'The length of "marsh" must be between 7 and 10', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(7, 10) instead.' +)); + +test('Scenario #16', expectMessageAndError( + static fn() => v::length(4, 10, false)->assert('reef'), + 'The length of "reef" must be greater than 4 and less than 10', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetweenExclusive(4, 10) instead.' +)); + +test('Scenario #17', expectMessageAndError( + static fn() => v::not(v::length(0, 15))->assert('valley'), + 'The length of "valley" must be greater than 15', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThanOrEqual(15) instead.' +)); + +test('Scenario #18', expectMessageAndError( + static fn() => v::not(v::length(0, 20, false))->assert('island'), + 'The length of "island" must not be less than 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(20) instead.' +)); + +test('Scenario #19', expectMessageAndError( + static fn() => v::not(v::length(5, null))->assert('plateau'), + 'The length of "plateau" must be less than 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(5) instead.' +)); + +test('Scenario #20', expectMessageAndError( + static fn() => v::not(v::length(3, null, false))->assert('fjord'), + 'The length of "fjord" must not be greater than 3', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(3) instead.' +)); + +test('Scenario #21', expectMessageAndError( + static fn() => v::not(v::length(5, 20))->assert('delta'), + 'The length of "delta" must not be between 5 and 20', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(5, 20) instead.' +)); + +test('Scenario #22', expectMessageAndError( + static fn() => v::not(v::length(5, 11, false))->assert('waterfall'), + 'The length of "waterfall" must not be greater than 5 or less than 11', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetweenExclusive(5, 11) instead.' +)); + +test('Scenario #23', expectMessageAndError( + static fn() => v::length(8, 8)->assert('estuary'), + 'The length of "estuary" must be equal to 8', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthEquals(8) instead.' +)); + +test('Scenario #24', expectMessageAndError( + static fn() => v::not(v::length(5, 5))->assert('grove'), + 'The length of "grove" must not be equal to 5', + 'Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthEquals(5) instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedMaxTest.php b/tests/feature/Transformers/DeprecatedMaxTest.php new file mode 100644 index 000000000..8daca169d --- /dev/null +++ b/tests/feature/Transformers/DeprecatedMaxTest.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessageAndError( + static fn() => v::max(10)->assert(11), + '11 must be less than or equal to 10', + 'Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead.', +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::not(v::max(10))->assert(5), + '5 must be greater than 10', + 'Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead.', +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::max('today')->assert('tomorrow'), + '"tomorrow" must be less than or equal to "today"', + 'Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::not(v::max('b'))->assert('a'), + '"a" must be greater than "b"', + 'Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedMinTest.php b/tests/feature/Transformers/DeprecatedMinTest.php new file mode 100644 index 000000000..37a1e42aa --- /dev/null +++ b/tests/feature/Transformers/DeprecatedMinTest.php @@ -0,0 +1,32 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessageAndError( + static fn() => v::min(INF)->assert(10), + '10 must be greater than or equal to `INF`', + 'Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::not(v::min(5))->assert(INF), + '`INF` must be less than 5', + 'Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::min('today')->assert('yesterday'), + '"yesterday" must be greater than or equal to "today"', + 'Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::not(v::min('a'))->assert('z'), + '"z" must be less than "a"', + 'Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead.' +)); diff --git a/tests/feature/Transformers/DeprecatedTypeTest.php b/tests/feature/Transformers/DeprecatedTypeTest.php new file mode 100644 index 000000000..fb4482f6c --- /dev/null +++ b/tests/feature/Transformers/DeprecatedTypeTest.php @@ -0,0 +1,80 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +test('Scenario #1', expectMessageAndError( + static fn() => v::type('array')->assert(1), + '1 must be an array', + 'The type() rule is deprecated and will be removed in the next major version. Use arrayType() instead.' +)); + +test('Scenario #2', expectMessageAndError( + static fn() => v::type('bool')->assert(1), + '1 must be a boolean', + 'The type() rule is deprecated and will be removed in the next major version. Use boolType() instead.' +)); + +test('Scenario #3', expectMessageAndError( + static fn() => v::type('boolean')->assert(1), + '1 must be a boolean', + 'The type() rule is deprecated and will be removed in the next major version. Use boolType() instead.' +)); + +test('Scenario #4', expectMessageAndError( + static fn() => v::type('callable')->assert(1), + '1 must be a callable', + 'The type() rule is deprecated and will be removed in the next major version. Use callableType() instead.' +)); + +test('Scenario #5', expectMessageAndError( + static fn() => v::type('double')->assert(1), + '1 must be float', + 'The type() rule is deprecated and will be removed in the next major version. Use floatType() instead.' +)); + +test('Scenario #6', expectMessageAndError( + static fn() => v::type('float')->assert(1), + '1 must be float', + 'The type() rule is deprecated and will be removed in the next major version. Use floatType() instead.' +)); + +test('Scenario #7', expectMessageAndError( + static fn() => v::type('int')->assert('1'), + '"1" must be an integer', + 'The type() rule is deprecated and will be removed in the next major version. Use intType() instead.' +)); + +test('Scenario #8', expectMessageAndError( + static fn() => v::type('integer')->assert('1'), + '"1" must be an integer', + 'The type() rule is deprecated and will be removed in the next major version. Use intType() instead.' +)); + +test('Scenario #9', expectMessageAndError( + static fn() => v::type('null')->assert(1), + '1 must be null', + 'The type() rule is deprecated and will be removed in the next major version. Use nullType() instead.' +)); + +test('Scenario #10', expectMessageAndError( + static fn() => v::type('object')->assert(1), + '1 must be an object', + 'The type() rule is deprecated and will be removed in the next major version. Use objectType() instead.' +)); + +test('Scenario #11', expectMessageAndError( + static fn() => v::type('resource')->assert(1), + '1 must be a resource', + 'The type() rule is deprecated and will be removed in the next major version. Use resourceType() instead.' +)); + +test('Scenario #12', expectMessageAndError( + static fn() => v::type('string')->assert(1), + '1 must be a string', + 'The type() rule is deprecated and will be removed in the next major version. Use stringType() instead.' +)); diff --git a/tests/feature/Transformers/PrefixTest.php b/tests/feature/Transformers/PrefixTest.php new file mode 100644 index 000000000..42a1d1134 --- /dev/null +++ b/tests/feature/Transformers/PrefixTest.php @@ -0,0 +1,66 @@ + + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); + +date_default_timezone_set('UTC'); + +test('Key', expectAll( + static fn() => v::keyEquals('foo', 12)->assert(['foo' => 10]), + 'foo must be equal to 12', + '- foo must be equal to 12', + ['foo' => 'foo must be equal to 12'] +)); + +test('Length', expectAll( + static fn() => v::lengthGreaterThan(3)->assert('foo'), + 'The length of "foo" must be greater than 3', + '- The length of "foo" must be greater than 3', + ['lengthGreaterThan' => 'The length of "foo" must be greater than 3'] +)); + +test('Max', expectAll( + static fn() => v::maxOdd()->assert([1, 2, 3, 4]), + 'As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number', + '- As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number', + ['maxOdd' => 'As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number'] +)); + +test('Min', expectAll( + static fn() => v::minEven()->assert([1, 2, 3]), + 'As the minimum from `[1, 2, 3]`, 1 must be an even number', + '- As the minimum from `[1, 2, 3]`, 1 must be an even number', + ['minEven' => 'As the minimum from `[1, 2, 3]`, 1 must be an even number'] +)); + +test('Not', expectAll( + static fn() => v::notBetween(1, 3)->assert(2), + '2 must not be between 1 and 3', + '- 2 must not be between 1 and 3', + ['notBetween' => '2 must not be between 1 and 3'] +)); + +test('NullOr', expectAll( + static fn() => v::nullOrBoolType()->assert('string'), + '"string" must be a boolean or must be null', + '- "string" must be a boolean or must be null', + ['nullOrBoolType' => '"string" must be a boolean or must be null'] +)); + +test('Property', expectAll( + static fn() => v::propertyBetween('foo', 1, 3)->assert((object) ['foo' => 5]), + 'foo must be between 1 and 3', + '- foo must be between 1 and 3', + ['foo' => 'foo must be between 1 and 3'] +)); + +test('UndefOr', expectAll( + static fn() => v::undefOrUrl()->assert('string'), + '"string" must be a URL or must be undefined', + '- "string" must be a URL or must be undefined', + ['undefOrUrl' => '"string" must be a URL or must be undefined'] +)); diff --git a/tests/integration/translator.phpt b/tests/feature/Translator.php similarity index 59% rename from tests/integration/translator.phpt rename to tests/feature/Translator.php index e75068407..117d93cf5 100644 --- a/tests/integration/translator.phpt +++ b/tests/feature/Translator.php @@ -1,7 +1,11 @@ ---FILE-- + * SPDX-License-Identifier: MIT + */ + +declare(strict_types=1); use Respect\Validation\Message\Translator\ArrayTranslator; use Respect\Validation\Validator; @@ -20,12 +24,17 @@ '{{name}} must be equal to {{compareTo}}' => '{{name}} deve ser igual a {{compareTo}}', ])); -exceptionFullMessage(static fn() => Validator::stringType()->lengthBetween(2, 15)->phone('US')->assert(0)); -exceptionMessage(static fn() => v::dateTimeDiff('years', v::equals(2))->assert('1972-02-09')); -?> ---EXPECT-- -- Todas as regras requeridas devem passar para 0 - - 0 must be a string - - O comprimento de 0 deve possuir de 2 a 15 caracteres - - 0 deve ser um número de telefone válido para o país Estados Unidos -O número de anos entre agora e 1972-02-09 deve ser igual a 2 +test('Scenario #1', expectFullMessage( + static fn() => Validator::stringType()->lengthBetween(2, 15)->phone('US')->assert(0), + <<<'MESSAGE' + - Todas as regras requeridas devem passar para 0 + - 0 must be a string + - O comprimento de 0 deve possuir de 2 a 15 caracteres + - 0 deve ser um número de telefone válido para o país Estados Unidos + MESSAGE, +)); + +test('Scenario #2', expectMessage( + static fn() => v::dateTimeDiff('years', v::equals(2))->assert('1972-02-09'), + 'O número de anos entre agora e 1972-02-09 deve ser igual a 2', +)); diff --git a/tests/integration/assert-with-properties.phpt b/tests/integration/assert-with-properties.phpt deleted file mode 100644 index f2c2c7c33..000000000 --- a/tests/integration/assert-with-properties.phpt +++ /dev/null @@ -1,48 +0,0 @@ ---FILE-- - [ - 'host' => 42, - 'user' => 'user', - 'password' => 'password', - 'schema' => 'schema', - ], - 'postgresql' => [ - 'host' => 'host', - 'user' => 42, - 'password' => 'password', - 'schema' => 'schema', - ], - ]; - $object = json_decode((string) json_encode($array)); - v::create() - ->property( - 'mysql', - v::create() - ->property('host', v::stringType()) - ->property('user', v::stringType()) - ->property('password', v::stringType()) - ->property('schema', v::stringType()) - ) - ->property( - 'postgresql', - v::create() - ->property('host', v::stringType()) - ->property('user', v::stringType()) - ->property('password', v::stringType()) - ->property('schema', v::stringType()) - ) - ->setName('the given data') - ->assert($object); -}); -?> ---EXPECT-- -- All of the required rules must pass for the given data - - These rules must pass for mysql - - host must be a string - - These rules must pass for postgresql - - user must be a string \ No newline at end of file diff --git a/tests/integration/assert-with-templates.phpt b/tests/integration/assert-with-templates.phpt deleted file mode 100644 index 82ef6eaea..000000000 --- a/tests/integration/assert-with-templates.phpt +++ /dev/null @@ -1,84 +0,0 @@ ---FILE-- - v::alwaysInvalid()->setTemplate('My string template in the chain')->assert(1) -); - -exceptionAll( - 'Template as an array in the chain', - static fn() => v::alwaysInvalid()->setTemplates(['alwaysInvalid' => 'My array template in the chain'])->assert(1) -); - -exceptionAll( - 'Runtime template as string', - static fn() => v::alwaysInvalid()->assert(1, 'My runtime template as string') -); - -exceptionAll( - 'Runtime template as an array', - static fn() => v::alwaysInvalid()->assert(1, ['alwaysInvalid' => 'My runtime template an array']) -); - -heading('Runtime template as an exception'); -try { - v::alwaysInvalid()->assert(1, new Exception('My runtime template as an exception')); -} catch (Throwable $exception) { - echo $exception->getMessage(); - echo PHP_EOL . PHP_EOL; -} - -heading('Runtime template as a callable'); -try { - v::alwaysInvalid() - ->assert(1, static fn(ValidationException $exception) => new Exception('My runtime template as an exception: ' . $exception->getMessage())); -} catch (Throwable $exception) { - echo $exception->getMessage(); - echo PHP_EOL . PHP_EOL; -} -?> ---EXPECT-- -Template as a string in the chain -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -My string template in the chain -- My string template in the chain -[ - 'alwaysInvalid' => 'My string template in the chain', -] - -Template as an array in the chain -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -My array template in the chain -- My array template in the chain -[ - 'alwaysInvalid' => 'My array template in the chain', -] - -Runtime template as string -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -My runtime template as string -- My runtime template as string -[ - 'alwaysInvalid' => 'My runtime template as string', -] - -Runtime template as an array -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -My runtime template an array -- My runtime template an array -[ - 'alwaysInvalid' => 'My runtime template an array', -] - -Runtime template as an exception -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -My runtime template as an exception - -Runtime template as a callable -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -My runtime template as an exception: 1 must be valid diff --git a/tests/integration/do_not_rely_on_nested_validation_exception_interface_for_check.phpt b/tests/integration/do_not_rely_on_nested_validation_exception_interface_for_check.phpt deleted file mode 100644 index 10e3020a7..000000000 --- a/tests/integration/do_not_rely_on_nested_validation_exception_interface_for_check.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---FILE-- - Validator::alnum('__')->lengthBetween(1, 15)->noWhitespace()->assert('really messed up screen#name') -); -?> ---EXPECT-- -"really messed up screen#name" must contain only letters (a-z), digits (0-9), and "__" \ No newline at end of file diff --git a/tests/integration/get_full_message_should_include_all_validation_messages_in_a_chain.phpt b/tests/integration/get_full_message_should_include_all_validation_messages_in_a_chain.phpt deleted file mode 100644 index 2109b8e54..000000000 --- a/tests/integration/get_full_message_should_include_all_validation_messages_in_a_chain.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---FILE-- - Validator::stringType()->lengthBetween(2, 15)->assert(0)); -?> ---EXPECT-- -- All of the required rules must pass for 0 - - 0 must be a string - - The length of 0 must be between 2 and 15 \ No newline at end of file diff --git a/tests/integration/get_messages.phpt b/tests/integration/get_messages.phpt deleted file mode 100644 index 0617868c5..000000000 --- a/tests/integration/get_messages.phpt +++ /dev/null @@ -1,53 +0,0 @@ ---FILE-- -key( - 'mysql', - v::create() - ->key('host', v::stringType()) - ->key('user', v::stringType()) - ->key('password', v::stringType()) - ->key('schema', v::stringType()) - ) - ->key( - 'postgresql', - v::create() - ->key('host', v::stringType()) - ->key('user', v::stringType()) - ->key('password', v::stringType()) - ->key('schema', v::stringType()) - ) - ->assert([ - 'mysql' => [ - 'host' => 42, - 'schema' => 42, - ], - 'postgresql' => [ - 'user' => 42, - 'password' => 42, - ], - ]); -}); -?> ---EXPECT-- -[ - '__root__' => 'All of the required rules must pass for `["mysql": ["host": 42, "schema": 42], "postgresql": ["user": 42, "password": 42]]`', - 'mysql' => [ - '__root__' => 'All of the required rules must pass for mysql', - 'host' => 'host must be a string', - 'user' => 'user must be present', - 'password' => 'password must be present', - 'schema' => 'schema must be a string', - ], - 'postgresql' => [ - '__root__' => 'All of the required rules must pass for postgresql', - 'host' => 'host must be present', - 'user' => 'user must be a string', - 'password' => 'password must be a string', - 'schema' => 'schema must be present', - ], -] \ No newline at end of file diff --git a/tests/integration/get_messages_should_include_all_validation_messages_in_a_chain.phpt b/tests/integration/get_messages_should_include_all_validation_messages_in_a_chain.phpt deleted file mode 100644 index e97144d39..000000000 --- a/tests/integration/get_messages_should_include_all_validation_messages_in_a_chain.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---FILE-- - 'u', - 'birthdate' => 'Not a date', - 'password' => '', - ]; - - Validator::create() - ->key('username', Validator::lengthBetween(2, 32)) - ->key('birthdate', Validator::dateTime()) - ->key('password', Validator::notEmpty()) - ->key('email', Validator::email()) - ->assert($input); -}); -?> ---EXPECT-- -[ - '__root__' => 'All of the required rules must pass for `["username": "u", "birthdate": "Not a date", "password": ""]`', - 'username' => 'The length of username must be between 2 and 32', - 'birthdate' => 'birthdate must be a valid date/time', - 'password' => 'password must not be empty', - 'email' => 'email must be present', -] diff --git a/tests/integration/get_messages_with_replacements.phpt b/tests/integration/get_messages_with_replacements.phpt deleted file mode 100644 index bcc05fed8..000000000 --- a/tests/integration/get_messages_with_replacements.phpt +++ /dev/null @@ -1,66 +0,0 @@ ---FILE-- -key( - 'mysql', - v::create() - ->key('host', v::stringType()) - ->key('user', v::stringType()) - ->key('password', v::stringType()) - ->key('schema', v::stringType()) - ) - ->key( - 'postgresql', - v::create() - ->key('host', v::stringType()) - ->key('user', v::stringType()) - ->key('password', v::stringType()) - ->key('schema', v::stringType()) - ) - ->assert( - [ - 'mysql' => [ - 'host' => 42, - 'schema' => 42, - ], - 'postgresql' => [ - 'user' => 42, - 'password' => 42, - ], - ], - [ - 'mysql' => [ - 'user' => 'Value should be a MySQL username', - 'host' => '`{{name}}` should be a MySQL host', - ], - 'postgresql' => [ - 'schema' => 'You must provide a valid PostgreSQL schema', - ], - ] - ); - } -); -?> ---EXPECT-- -[ - '__root__' => 'All of the required rules must pass for `["mysql": ["host": 42, "schema": 42], "postgresql": ["user": 42, "password": 42]]`', - 'mysql' => [ - '__root__' => 'All of the required rules must pass for mysql', - 'host' => '`host` should be a MySQL host', - 'user' => 'Value should be a MySQL username', - 'password' => 'password must be present', - 'schema' => 'schema must be a string', - ], - 'postgresql' => [ - '__root__' => 'All of the required rules must pass for postgresql', - 'host' => 'host must be present', - 'user' => 'user must be a string', - 'password' => 'password must be a string', - 'schema' => 'You must provide a valid PostgreSQL schema', - ], -] \ No newline at end of file diff --git a/tests/integration/issues/1033.phpt b/tests/integration/issues/1033.phpt deleted file mode 100644 index b9bfa44d6..000000000 --- a/tests/integration/issues/1033.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---FILE-- - v::each(v::equals(1))->assert(['A', 'B', 'B']) -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1033 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"A" must be equal to 1 -- Each item in `["A", "B", "B"]` must be valid - - "A" must be equal to 1 - - "B" must be equal to 1 - - "B" must be equal to 1 -[ - '__root__' => 'Each item in `["A", "B", "B"]` must be valid', - 'equals.1' => '"A" must be equal to 1', - 'equals.2' => '"B" must be equal to 1', - 'equals.3' => '"B" must be equal to 1', -] diff --git a/tests/integration/issues/1244.phpt b/tests/integration/issues/1244.phpt deleted file mode 100644 index 40674dc5f..000000000 --- a/tests/integration/issues/1244.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---FILE-- - v::key('firstname', v::notBlank()->setName('First Name'))->assert([]) -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1244 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -First Name must be present -- First Name must be present -[ - 'firstname' => 'First Name must be present', -] diff --git a/tests/integration/issues/1333.phpt b/tests/integration/issues/1333.phpt deleted file mode 100644 index ffd0c377e..000000000 --- a/tests/integration/issues/1333.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---FILE-- - v::noWhitespace()->email()->setName('User Email')->assert('not email') -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1333 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -User Email must not contain whitespaces -- All of the required rules must pass for User Email - - User Email must not contain whitespaces - - User Email must be a valid email address -[ - '__root__' => 'All of the required rules must pass for User Email', - 'noWhitespace' => 'User Email must not contain whitespaces', - 'email' => 'User Email must be a valid email address', -] diff --git a/tests/integration/issues/1334.phpt b/tests/integration/issues/1334.phpt deleted file mode 100644 index 33e785080..000000000 --- a/tests/integration/issues/1334.phpt +++ /dev/null @@ -1,46 +0,0 @@ ---FILE-- -iterableType()->each( - v::key('street', v::stringType()->notEmpty()) - ->key('region', v::stringType()->notEmpty()) - ->key('country', v::stringType()->notEmpty()) - ->keyOptional('other', v::nullOr(v::notEmpty()->stringType())) - )->assert( - [ - ['region' => 'Oregon', 'country' => 'USA', 'other' => 123], - ['street' => '', 'region' => 'Oregon', 'country' => 'USA'], - ['street' => 123, 'region' => 'Oregon', 'country' => 'USA'], - ] - ); -}); - -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1334 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -street must be present -- Each item in `[["region": "Oregon", "country": "USA", "other": 123], ["street": "", "region": "Oregon", "country": "USA"], ["s ... ]` must be valid - - These rules must pass for `["region": "Oregon", "country": "USA", "other": 123]` - - street must be present - - These rules must pass for other - - other must be a string or must be null - - These rules must pass for `["street": "", "region": "Oregon", "country": "USA"]` - - street must not be empty - - These rules must pass for `["street": 123, "region": "Oregon", "country": "USA"]` - - street must be a string -[ - 'each' => [ - '__root__' => 'Each item in `[["region": "Oregon", "country": "USA", "other": 123], ["street": "", "region": "Oregon", "country": "USA"], ["s ... ]` must be valid', - 'allOf.1' => [ - '__root__' => 'These rules must pass for `["region": "Oregon", "country": "USA", "other": 123]`', - 'street' => 'street must be present', - 'other' => 'other must be a string or must be null', - ], - 'allOf.2' => 'street must not be empty', - 'allOf.3' => 'street must be a string', - ], -] diff --git a/tests/integration/issues/1348.phpt b/tests/integration/issues/1348.phpt deleted file mode 100644 index 166a07391..000000000 --- a/tests/integration/issues/1348.phpt +++ /dev/null @@ -1,84 +0,0 @@ ---FILE-- - 'Honda', 'model' => 'Accord'], - ['manufacturer' => 'Toyota', 'model' => 'Rav4'], - ['manufacturer' => 'Ford', 'model' => 'not real'], - ['manufacturer' => 'Honda', 'model' => 'not valid'], -]; - -exceptionAll( - 'https://github.com/Respect/Validation/issues/1289', - static fn () => Validator::arrayType()->each( - Validator::oneOf( - Validator::key('manufacturer', Validator::equals('Honda')) - ->key('model', Validator::in(['Accord', 'Fit'])), - Validator::key('manufacturer', Validator::equals('Toyota')) - ->key('model', Validator::in(['Rav4', 'Camry'])), - Validator::key('manufacturer', Validator::equals('Ford')) - ->key('model', Validator::in(['F150', 'Bronco'])) - ) - )->assert($cars) -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1289 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -manufacturer must be equal to "Honda" -- Each item in `[["manufacturer": "Honda", "model": "Accord"], ["manufacturer": "Toyota", "model": "Rav4"], ["manufacturer": "Fo ... ]` must be valid - - Only one of these rules must pass for `["manufacturer": "Ford", "model": "not real"]` - - All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]` - - manufacturer must be equal to "Honda" - - model must be in `["Accord", "Fit"]` - - All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]` - - manufacturer must be equal to "Toyota" - - model must be in `["Rav4", "Camry"]` - - These rules must pass for `["manufacturer": "Ford", "model": "not real"]` - - model must be in `["F150", "Bronco"]` - - Only one of these rules must pass for `["manufacturer": "Honda", "model": "not valid"]` - - These rules must pass for `["manufacturer": "Honda", "model": "not valid"]` - - model must be in `["Accord", "Fit"]` - - All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]` - - manufacturer must be equal to "Toyota" - - model must be in `["Rav4", "Camry"]` - - All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]` - - manufacturer must be equal to "Ford" - - model must be in `["F150", "Bronco"]` -[ - 'each' => [ - '__root__' => 'Each item in `[["manufacturer": "Honda", "model": "Accord"], ["manufacturer": "Toyota", "model": "Rav4"], ["manufacturer": "Fo ... ]` must be valid', - 'oneOf.3' => [ - '__root__' => 'Only one of these rules must pass for `["manufacturer": "Ford", "model": "not real"]`', - 'allOf.1' => [ - '__root__' => 'All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]`', - 'manufacturer' => 'manufacturer must be equal to "Honda"', - 'model' => 'model must be in `["Accord", "Fit"]`', - ], - 'allOf.2' => [ - '__root__' => 'All of the required rules must pass for `["manufacturer": "Ford", "model": "not real"]`', - 'manufacturer' => 'manufacturer must be equal to "Toyota"', - 'model' => 'model must be in `["Rav4", "Camry"]`', - ], - 'allOf.3' => 'model must be in `["F150", "Bronco"]`', - ], - 'oneOf.4' => [ - '__root__' => 'Only one of these rules must pass for `["manufacturer": "Honda", "model": "not valid"]`', - 'allOf.1' => 'model must be in `["Accord", "Fit"]`', - 'allOf.2' => [ - '__root__' => 'All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]`', - 'manufacturer' => 'manufacturer must be equal to "Toyota"', - 'model' => 'model must be in `["Rav4", "Camry"]`', - ], - 'allOf.3' => [ - '__root__' => 'All of the required rules must pass for `["manufacturer": "Honda", "model": "not valid"]`', - 'manufacturer' => 'manufacturer must be equal to "Ford"', - 'model' => 'model must be in `["F150", "Bronco"]`', - ], - ], - ], -] diff --git a/tests/integration/issues/1376.phpt b/tests/integration/issues/1376.phpt deleted file mode 100644 index cf7106102..000000000 --- a/tests/integration/issues/1376.phpt +++ /dev/null @@ -1,36 +0,0 @@ ---FILE-- -stringType()) - ->property('description', v::stringType()) - ->property('author', v::intType()->lengthBetween(1, 2)) - ->property('user', v::intVal()->lengthBetween(1, 2)) - ->assert((object) ['author' => 'foo']); -}); - -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1376 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -title must be present -- All of the required rules must pass for `stdClass { +$author="foo" }` - - title must be present - - description must be present - - All of the required rules must pass for author - - author must be an integer - - The length of author must be between 1 and 2 - - user must be present -[ - '__root__' => 'All of the required rules must pass for `stdClass { +$author="foo" }`', - 'title' => 'title must be present', - 'description' => 'description must be present', - 'author' => [ - '__root__' => 'All of the required rules must pass for author', - 'intType' => 'author must be an integer', - 'lengthBetween' => 'The length of author must be between 1 and 2', - ], - 'user' => 'user must be present', -] diff --git a/tests/integration/issues/1469.phpt b/tests/integration/issues/1469.phpt deleted file mode 100644 index fb0798bf8..000000000 --- a/tests/integration/issues/1469.phpt +++ /dev/null @@ -1,50 +0,0 @@ ---FILE-- - [ - [ - 'product_title' => 'test', - 'quantity' => 'test', - ], - [ - 'product_title2' => 'test', - ], - ], - ]; - - v::arrayVal()->keySet( - v::key('order_items', v::arrayVal()->each(v::keySet( - v::key('product_title', v::stringVal()->notEmpty()), - v::key('quantity', v::intVal()->notEmpty()), - ))->notEmpty()), - )->assert($data); -}); - -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1469 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -quantity must be an integer value -- Each item in order_items must be valid - - order_items validation failed - - quantity must be an integer value - - order_items contains both missing and extra keys - - product_title must be present - - quantity must be present - - product_title2 must not be present -[ - 'keySet' => [ - '__root__' => 'Each item in order_items must be valid', - 'keySet.1' => 'quantity must be an integer value', - 'keySet.2' => [ - '__root__' => 'order_items contains both missing and extra keys', - 'product_title' => 'product_title must be present', - 'quantity' => 'quantity must be present', - 'product_title2' => 'product_title2 must not be present', - ], - ], -] diff --git a/tests/integration/issues/1477.phpt b/tests/integration/issues/1477.phpt deleted file mode 100644 index b4865256d..000000000 --- a/tests/integration/issues/1477.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---FILE-- -setTemplate('{{name}} is not good!') - )->assert(['Address' => 'cvejvn']); -}); - -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/1477 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Address is not good! -- Address is not good! -[ - 'Address' => 'Address is not good!', -] diff --git a/tests/integration/issues/179.phpt b/tests/integration/issues/179.phpt deleted file mode 100644 index 0a0259593..000000000 --- a/tests/integration/issues/179.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---FILE-- - 1, - 'password' => 'my_password', - 'schema' => 'my_schema', -]; - -$validator = v::arrayType(); -$validator->setName('Settings'); -$validator->key('host', v::stringType()); -$validator->key('user', v::stringType()); -$validator->key('password', v::stringType()); -$validator->key('schema', v::stringType()); - -exceptionAll('https://github.com/Respect/Validation/issues/179', static fn() => $validator->assert($config)); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/179 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -host must be a string -- These rules must pass for Settings - - host must be a string - - user must be present -[ - '__root__' => 'These rules must pass for Settings', - 'host' => 'host must be a string', - 'user' => 'user must be present', -] diff --git a/tests/integration/issues/425.phpt b/tests/integration/issues/425.phpt deleted file mode 100644 index 0d3d2d4ef..000000000 --- a/tests/integration/issues/425.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---FILE-- -key('age', v::intType()->notEmpty()->noneOf(v::stringType(), v::arrayType())) - ->key('reference', v::stringType()->notEmpty()->lengthBetween(1, 50)); - -exceptionAll('https://github.com/Respect/Validation/issues/425', static fn() => $validator->assert(['age' => 1])); -exceptionAll('https://github.com/Respect/Validation/issues/425', static fn() => $validator->assert(['reference' => 'QSF1234'])); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/425 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -reference must be present -- reference must be present -[ - 'reference' => 'reference must be present', -] - -https://github.com/Respect/Validation/issues/425 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -age must be present -- age must be present -[ - 'age' => 'age must be present', -] diff --git a/tests/integration/issues/446.phpt b/tests/integration/issues/446.phpt deleted file mode 100644 index 1c2674ac9..000000000 --- a/tests/integration/issues/446.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---FILE-- - 'w', - 'email' => 'hello@hello.com', -]; - -exceptionAll('https://github.com/Respect/Validation/issues/446', static function () use ($arr): void { - v::create() - ->key('name', v::lengthBetween(2, 32)) - ->key('email', v::email()) - ->assert($arr); -}); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/446 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The length of name must be between 2 and 32 -- The length of name must be between 2 and 32 -[ - 'name' => 'The length of name must be between 2 and 32', -] diff --git a/tests/integration/issues/619.phpt b/tests/integration/issues/619.phpt deleted file mode 100644 index 228cde371..000000000 --- a/tests/integration/issues/619.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---FILE-- - v::instance(stdClass::class)->setTemplate('invalid object')->assert('test') -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/619 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -invalid object -- invalid object -[ - 'instance' => 'invalid object', -] diff --git a/tests/integration/issues/739.phpt b/tests/integration/issues/739.phpt deleted file mode 100644 index 629dfe1aa..000000000 --- a/tests/integration/issues/739.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---FILE-- - v::when(v::alwaysInvalid(), v::alwaysValid())->assert('foo') -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/739 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"foo" is invalid -- "foo" is invalid -[ - 'alwaysInvalid' => '"foo" is invalid', -] diff --git a/tests/integration/issues/799.phpt b/tests/integration/issues/799.phpt deleted file mode 100644 index c8142e45e..000000000 --- a/tests/integration/issues/799.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---FILE-- -call( - [new CountableStub(1), 'count'], - v::arrayVal()->key('scheme', v::startsWith('https')) - ) - ->assert($input); -}); - -exceptionAll('https://github.com/Respect/Validation/issues/799', static function () use ($input): void { - v::create() - ->call( - static function ($url) { - return parse_url($url); - }, - v::arrayVal()->key('scheme', v::startsWith('https')) - ) - ->assert($input); -}); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/799 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -1 must be an array value -- All of the required rules must pass for 1 - - 1 must be an array value - - scheme must be present -[ - '__root__' => 'All of the required rules must pass for 1', - 'arrayVal' => '1 must be an array value', - 'scheme' => 'scheme must be present', -] - -https://github.com/Respect/Validation/issues/799 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -scheme must start with "https" -- scheme must start with "https" -[ - 'scheme' => 'scheme must start with "https"', -] diff --git a/tests/integration/issues/805.phpt b/tests/integration/issues/805.phpt deleted file mode 100644 index 26b74ef22..000000000 --- a/tests/integration/issues/805.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---FILE-- - v::key('email', v::email()->setTemplate('WRONG EMAIL!!!!!!'))->assert(['email' => 'qwe']) -); -?> ---EXPECT-- -https://github.com/Respect/Validation/issues/805 -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -WRONG EMAIL!!!!!! -- WRONG EMAIL!!!!!! -[ - 'email' => 'WRONG EMAIL!!!!!!', -] diff --git a/tests/integration/keys_as_validator_names.phpt b/tests/integration/keys_as_validator_names.phpt deleted file mode 100644 index eb54d5050..000000000 --- a/tests/integration/keys_as_validator_names.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---FILE-- -key('username', Validator::length(Validator::between(2, 32))) - ->key('birthdate', Validator::dateTime()) - ->setName('User Subscription Form') - ->assert(['username' => '0', 'birthdate' => 'Whatever']); -}); -?> ---EXPECT-- -- All of the required rules must pass for User Subscription Form - - The length of username must be between 2 and 32 - - birthdate must be a valid date/time diff --git a/tests/integration/lib/helpers.php b/tests/integration/lib/helpers.php deleted file mode 100644 index 2a3ec01b6..000000000 --- a/tests/integration/lib/helpers.php +++ /dev/null @@ -1,66 +0,0 @@ - - * SPDX-License-Identifier: MIT - */ - -declare(strict_types=1); - -use Respect\Validation\Exceptions\ValidationException; -use Respect\Validation\Rule; -use Symfony\Component\VarExporter\VarExporter; - -function heading(string $heading): void -{ - echo $heading . PHP_EOL; - echo str_repeat('⎺', strlen($heading)) . PHP_EOL; -} - -function exceptionAll(string $heading, callable $callable): void -{ - heading($heading); - exceptionMessage($callable, 'No exception was thrown'); - exceptionFullMessage($callable, 'No exception was thrown'); - exceptionMessages($callable, 'No exception was thrown'); - echo PHP_EOL; -} - -function exceptionMessage(callable $callable, string $fallbackMessage = 'No exception was thrown'): void -{ - try { - $callable(); - echo $fallbackMessage . PHP_EOL; - } catch (ValidationException $exception) { - echo $exception->getMessage() . PHP_EOL; - } -} - -function exceptionMessages(callable $callable, string $fallbackMessage = 'No exception was thrown'): void -{ - try { - $callable(); - echo $fallbackMessage . PHP_EOL; - } catch (ValidationException $exception) { - echo VarExporter::export($exception->getMessages()) . PHP_EOL; - } -} - -function exceptionFullMessage(callable $callable, string $fallbackMessage = 'No exception was thrown'): void -{ - try { - $callable(); - echo $fallbackMessage . PHP_EOL; - } catch (ValidationException $exception) { - echo $exception->getFullMessage() . PHP_EOL; - } -} - -/** @param array}> $scenarios */ -function run(array $scenarios): void -{ - foreach ($scenarios as $heading => $data) { - [$rule, $input, $template] = array_pad($data, 3, null); - exceptionAll($heading, static fn() => $rule->assert($input, $template)); - } -} diff --git a/tests/integration/not_should_work_by_builder.phpt b/tests/integration/not_should_work_by_builder.phpt deleted file mode 100644 index 4718e2d5a..000000000 --- a/tests/integration/not_should_work_by_builder.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -not() should work by builder ---FILE-- -isValid(10)); -?> ---EXPECT-- -bool(false) diff --git a/tests/integration/not_with_recursion.phpt b/tests/integration/not_with_recursion.phpt deleted file mode 100644 index 9ffedd80d..000000000 --- a/tests/integration/not_with_recursion.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---FILE-- -positive() - ) - ) - ) - ) -); - -exceptionMessage(static fn() => $validator->assert(2)); -exceptionFullMessage(static fn() => $validator->assert(2)); -?> ---EXPECT-- -2 must not be an integer value -- These rules must not pass for 2 - - 2 must not be an integer value - - 2 must not be a positive number \ No newline at end of file diff --git a/tests/integration/not_without_recursion.phpt b/tests/integration/not_without_recursion.phpt deleted file mode 100644 index 4b35633ed..000000000 --- a/tests/integration/not_without_recursion.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---FILE-- -positive() - ); - $validator->assert(2); -}); -?> ---EXPECT-- -2 must not be an integer value \ No newline at end of file diff --git a/tests/integration/readme/custom_messages.phpt b/tests/integration/readme/custom_messages.phpt deleted file mode 100644 index d56a923ae..000000000 --- a/tests/integration/readme/custom_messages.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::alnum() - ->noWhitespace() - ->length(v::between(1, 15)) - ->assert('really messed up screen#name', [ - 'alnum' => '{{name}} must contain only letters and digits', - 'noWhitespace' => '{{name}} cannot contain spaces', - 'length' => '{{name}} must not have more than 15 chars', - ]) -); -?> ---EXPECT-- -[ - '__root__' => 'All of the required rules must pass for "really messed up screen#name"', - 'alnum' => '"really messed up screen#name" must contain only letters and digits', - 'noWhitespace' => '"really messed up screen#name" cannot contain spaces', - 'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15', -] diff --git a/tests/integration/readme/example_1.phpt b/tests/integration/readme/example_1.phpt deleted file mode 100644 index 1f1bc6ee2..000000000 --- a/tests/integration/readme/example_1.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---FILE-- -name = 'Alexandre'; -$user->birthdate = '1987-07-01'; - -$userValidator = v::property('name', v::stringType()->length(v::between(1, 32))) - ->property('birthdate', v::dateTimeDiff('years', v::greaterThanOrEqual(18))); - -$userValidator->assert($user); - -echo 'Nothing to fail'; -?> ---EXPECT-- -Nothing to fail diff --git a/tests/integration/readme/getting_messages_as_an_array.phpt b/tests/integration/readme/getting_messages_as_an_array.phpt deleted file mode 100644 index d2b00b2c0..000000000 --- a/tests/integration/readme/getting_messages_as_an_array.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---FILE-- - v::alnum()->noWhitespace()->lengthBetween(1, 15)->assert('really messed up screen#name') -); -?> ---EXPECT-- -[ - '__root__' => 'All of the required rules must pass for "really messed up screen#name"', - 'alnum' => '"really messed up screen#name" must contain only letters (a-z) and digits (0-9)', - 'noWhitespace' => '"really messed up screen#name" must not contain whitespaces', - 'lengthBetween' => 'The length of "really messed up screen#name" must be between 1 and 15', -] \ No newline at end of file diff --git a/tests/integration/rules/allOf.phpt b/tests/integration/rules/allOf.phpt deleted file mode 100644 index e805cae13..000000000 --- a/tests/integration/rules/allOf.phpt +++ /dev/null @@ -1,73 +0,0 @@ ---FILE-- - [v::allOf(v::intType(), v::negative()), '2'], - 'Wrapped by "not"' => [v::not(v::allOf(v::intType(), v::positive())), 3], - 'Wrapping "not"' => [v::allOf(v::not(v::intType()), v::greaterThan(2)), 4], - 'With a single template' => [v::allOf(v::stringType(), v::arrayType()), 5, 'This is a single template'], - 'With multiple templates' => [ - v::allOf(v::stringType(), v::uppercase()), - 5, - [ - '__root__' => 'Two things are wrong', - 'stringType' => 'Template for "stringType"', - 'uppercase' => 'Template for "uppercase"', - ], - ], -]); -?> ---EXPECT-- -Two rules -⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"2" must be an integer -- All of the required rules must pass for "2" - - "2" must be an integer - - "2" must be a negative number -[ - '__root__' => 'All of the required rules must pass for "2"', - 'intType' => '"2" must be an integer', - 'negative' => '"2" must be a negative number', -] - -Wrapped by "not" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -3 must not be an integer -- These rules must not pass for 3 - - 3 must not be an integer - - 3 must not be a positive number -[ - '__root__' => 'These rules must not pass for 3', - 'intType' => '3 must not be an integer', - 'positive' => '3 must not be a positive number', -] - -Wrapping "not" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -4 must not be an integer -- 4 must not be an integer -[ - 'notIntType' => '4 must not be an integer', -] - -With a single template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -This is a single template -- This is a single template -[ - 'allOf' => 'This is a single template', -] - -With multiple templates -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Template for "stringType" -- Two things are wrong - - Template for "stringType" - - Template for "uppercase" -[ - '__root__' => 'Two things are wrong', - 'stringType' => 'Template for "stringType"', - 'uppercase' => 'Template for "uppercase"', -] diff --git a/tests/integration/rules/alnum.phpt b/tests/integration/rules/alnum.phpt deleted file mode 100644 index 76cc23d95..000000000 --- a/tests/integration/rules/alnum.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::alnum()->assert('abc%1')); -exceptionMessage(static fn() => v::alnum(' ')->assert('abc%2')); -exceptionMessage(static fn() => v::not(v::alnum())->assert('abcd3')); -exceptionMessage(static fn() => v::not(v::alnum('% '))->assert('abc%4')); -exceptionFullMessage(static fn() => v::alnum()->assert('abc^1')); -exceptionFullMessage(static fn() => v::not(v::alnum())->assert('abcd2')); -exceptionFullMessage(static fn() => v::alnum('* &%')->assert('abc^3')); -exceptionFullMessage(static fn() => v::not(v::alnum('^'))->assert('abc^4')); -?> ---EXPECT-- -"abc%1" must contain only letters (a-z) and digits (0-9) -"abc%2" must contain only letters (a-z), digits (0-9), and " " -"abcd3" must not contain letters (a-z) or digits (0-9) -"abc%4" must not contain letters (a-z), digits (0-9), or "% " -- "abc^1" must contain only letters (a-z) and digits (0-9) -- "abcd2" must not contain letters (a-z) or digits (0-9) -- "abc^3" must contain only letters (a-z), digits (0-9), and "* &%" -- "abc^4" must not contain letters (a-z), digits (0-9), or "^" diff --git a/tests/integration/rules/alpha.phpt b/tests/integration/rules/alpha.phpt deleted file mode 100644 index 83650702b..000000000 --- a/tests/integration/rules/alpha.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::alpha()->assert('aaa%a')); -exceptionMessage(static fn() => v::alpha(' ')->assert('bbb%b')); -exceptionMessage(static fn() => v::not(v::alpha())->assert('ccccc')); -exceptionMessage(static fn() => v::not(v::alpha('% '))->assert('ddd%d')); -exceptionFullMessage(static fn() => v::alpha()->assert('eee^e')); -exceptionFullMessage(static fn() => v::not(v::alpha())->assert('fffff')); -exceptionFullMessage(static fn() => v::alpha('* &%')->assert('ggg^g')); -exceptionFullMessage(static fn() => v::not(v::alpha('^'))->assert('hhh^h')); -?> ---EXPECT-- -"aaa%a" must contain only letters (a-z) -"bbb%b" must contain only letters (a-z) and " " -"ccccc" must not contain letters (a-z) -"ddd%d" must not contain letters (a-z) or "% " -- "eee^e" must contain only letters (a-z) -- "fffff" must not contain letters (a-z) -- "ggg^g" must contain only letters (a-z) and "* &%" -- "hhh^h" must not contain letters (a-z) or "^" diff --git a/tests/integration/rules/alwaysInvalid.phpt b/tests/integration/rules/alwaysInvalid.phpt deleted file mode 100644 index f58351381..000000000 --- a/tests/integration/rules/alwaysInvalid.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---FILE-- - v::alwaysInvalid()->assert('whatever')); -exceptionFullMessage(static fn() => v::alwaysInvalid()->assert('')); -?> ---EXPECT-- -"whatever" must be valid -- "" must be valid \ No newline at end of file diff --git a/tests/integration/rules/alwaysValid.phpt b/tests/integration/rules/alwaysValid.phpt deleted file mode 100644 index 1badfc0af..000000000 --- a/tests/integration/rules/alwaysValid.phpt +++ /dev/null @@ -1,11 +0,0 @@ ---FILE-- - v::not(v::alwaysValid())->assert(true)); -exceptionFullMessage(static fn() => v::not(v::alwaysValid())->assert(true)); -?> ---EXPECT-- -`true` must be invalid -- `true` must be invalid \ No newline at end of file diff --git a/tests/integration/rules/arrayType.phpt b/tests/integration/rules/arrayType.phpt deleted file mode 100644 index fbd7304ab..000000000 --- a/tests/integration/rules/arrayType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::arrayType()->assert('teste')); -exceptionMessage(static fn() => v::not(v::arrayType())->assert([])); -exceptionFullMessage(static fn() => v::arrayType()->assert(new ArrayObject())); -exceptionFullMessage(static fn() => v::not(v::arrayType())->assert([1, 2, 3])); -?> ---EXPECT-- -"teste" must be an array -`[]` must not be an array -- `ArrayObject { getArrayCopy() => [] }` must be an array -- `[1, 2, 3]` must not be an array \ No newline at end of file diff --git a/tests/integration/rules/arrayVal.phpt b/tests/integration/rules/arrayVal.phpt deleted file mode 100644 index ef419fe9b..000000000 --- a/tests/integration/rules/arrayVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::arrayVal()->assert('Bla %123')); -exceptionMessage(static fn() => v::not(v::arrayVal())->assert([42])); -exceptionFullMessage(static fn() => v::arrayVal()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::arrayVal())->assert(new ArrayObject([2, 3]))); -?> ---EXPECT-- -"Bla %123" must be an array value -`[42]` must not be an array value -- `stdClass {}` must be an array value -- `ArrayObject { getArrayCopy() => [2, 3] }` must not be an array value diff --git a/tests/integration/rules/attributes.phpt b/tests/integration/rules/attributes.phpt deleted file mode 100644 index 236d1aeb8..000000000 --- a/tests/integration/rules/attributes.phpt +++ /dev/null @@ -1,78 +0,0 @@ ---FILE-- - [v::attributes(), new WithAttributes('', 'john.doe@gmail.com', '2024-06-23')], - 'Inverted' => [v::attributes(), new WithAttributes('John Doe', 'john.doe@gmail.com', '2024-06-23', '+1234567890')], - 'Not an object' => [v::attributes(), []], - 'Nullable' => [v::attributes(), new WithAttributes('John Doe', 'john.doe@gmail.com', '2024-06-23', 'not a phone number')], - 'Multiple attributes, all failed' => [v::attributes(), new WithAttributes('', 'not an email', 'not a date', 'not a phone number')], - 'Multiple attributes, one failed' => [v::attributes(), new WithAttributes('John Doe', 'john.doe@gmail.com', '22 years ago')], -]); -?> ---EXPECTF-- -Default -⎺⎺⎺⎺⎺⎺⎺ -name must not be empty -- name must not be empty -[ - 'name' => 'name must not be empty', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -phone must be a valid telephone number or must be null -- phone must be a valid telephone number or must be null -[ - 'phone' => 'phone must be a valid telephone number or must be null', -] - -Not an object -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -`[]` must be an object -- `[]` must be an object -[ - 'attributes' => '`[]` must be an object', -] - -Nullable -⎺⎺⎺⎺⎺⎺⎺⎺ -phone must be a valid telephone number or must be null -- phone must be a valid telephone number or must be null -[ - 'phone' => 'phone must be a valid telephone number or must be null', -] - -Multiple attributes, all failed -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -name must not be empty -- All of the required rules must pass for `Respect\Validation\Test\Stubs\WithAttributes { +$name="" +$email="not an email" +$birthdate="not a date" +$phone ... }` - - name must not be empty - - email must be a valid email address - - All of the required rules must pass for birthdate - - birthdate must be a valid date in the format "%d-%d-%d" - - For comparison with now, birthdate must be a valid datetime - - phone must be a valid telephone number or must be null -[ - '__root__' => 'All of the required rules must pass for `Respect\\Validation\\Test\\Stubs\\WithAttributes { +$name="" +$email="not an email" +$birthdate="not a date" +$phone ... }`', - 'name' => 'name must not be empty', - 'email' => 'email must be a valid email address', - 'birthdate' => [ - '__root__' => 'All of the required rules must pass for birthdate', - 'date' => 'birthdate must be a valid date in the format "%d-%d-%d"', - 'dateTimeDiffLessThanOrEqual' => 'For comparison with now, birthdate must be a valid datetime', - ], - 'phone' => 'phone must be a valid telephone number or must be null', -] - -Multiple attributes, one failed -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -birthdate must be a valid date in the format "%d-%d-%d" -- birthdate must be a valid date in the format "%d-%d-%d" -[ - 'birthdate' => 'birthdate must be a valid date in the format "%d-%d-%d"', -] diff --git a/tests/integration/rules/base.phpt b/tests/integration/rules/base.phpt deleted file mode 100644 index 3e0e4fed1..000000000 --- a/tests/integration/rules/base.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::base(61)->assert('Z01xSsg5675hic20dj')); -exceptionFullMessage(static fn() => v::base(2)->assert('')); -exceptionMessage(static fn() => v::not(v::base(2))->assert('011010001')); -exceptionFullMessage(static fn() => v::not(v::base(2))->assert('011010001')); -?> ---EXPECT-- -"Z01xSsg5675hic20dj" must be a number in base 61 -- "" must be a number in base 2 -"011010001" must not be a number in base 2 -- "011010001" must not be a number in base 2 \ No newline at end of file diff --git a/tests/integration/rules/base64.phpt b/tests/integration/rules/base64.phpt deleted file mode 100644 index 4dc709d6d..000000000 --- a/tests/integration/rules/base64.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::base64()->assert('=c3VyZS4')); -exceptionMessage(static fn() => v::not(v::base64())->assert('c3VyZS4=')); -exceptionFullMessage(static fn() => v::base64()->assert('=c3VyZS4')); -exceptionFullMessage(static fn() => v::not(v::base64())->assert('c3VyZS4=')); -?> ---EXPECT-- -"=c3VyZS4" must be a base64 encoded string -"c3VyZS4=" must not be a base64 encoded string -- "=c3VyZS4" must be a base64 encoded string -- "c3VyZS4=" must not be a base64 encoded string \ No newline at end of file diff --git a/tests/integration/rules/beetwen.phpt b/tests/integration/rules/beetwen.phpt deleted file mode 100644 index 1ce71dc31..000000000 --- a/tests/integration/rules/beetwen.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - v::between(1, 2)->assert(0)); -exceptionMessage(static fn() => v::not(v::between('yesterday', 'tomorrow'))->assert('today')); -exceptionFullMessage(static fn() => v::between('a', 'c')->assert('d')); -exceptionFullMessage(static fn() => v::not(v::between(-INF, INF))->assert(0)); -exceptionFullMessage(static fn() => v::not(v::between('a', 'b'))->assert('a')); -exceptionFullMessage(static fn() => v::not(v::between(1, 42))->assert(41)); -?> ---EXPECT-- -0 must be between 1 and 2 -"today" must not be between "yesterday" and "tomorrow" -- "d" must be between "a" and "c" -- 0 must not be between `-INF` and `INF` -- "a" must not be between "a" and "b" -- 41 must not be between 1 and 42 diff --git a/tests/integration/rules/betweenExclusive.phpt b/tests/integration/rules/betweenExclusive.phpt deleted file mode 100644 index cc1199c1f..000000000 --- a/tests/integration/rules/betweenExclusive.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---FILE-- - [v::betweenExclusive(1, 10), 12], - 'Inverted' => [v::not(v::betweenExclusive(1, 10)), 5], - 'With template' => [v::betweenExclusive(1, 10), 12, 'Bewildered bees buzzed between blooming begonias'], - 'With name' => [v::betweenExclusive(1, 10)->setName('Range'), 10], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -12 must be greater than 1 and less than 10 -- 12 must be greater than 1 and less than 10 -[ - 'betweenExclusive' => '12 must be greater than 1 and less than 10', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -5 must not be greater than 1 or less than 10 -- 5 must not be greater than 1 or less than 10 -[ - 'notBetweenExclusive' => '5 must not be greater than 1 or less than 10', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Bewildered bees buzzed between blooming begonias -- Bewildered bees buzzed between blooming begonias -[ - 'betweenExclusive' => 'Bewildered bees buzzed between blooming begonias', -] - -With name -⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Range must be greater than 1 and less than 10 -- Range must be greater than 1 and less than 10 -[ - 'betweenExclusive' => 'Range must be greater than 1 and less than 10', -] diff --git a/tests/integration/rules/boolType.phpt b/tests/integration/rules/boolType.phpt deleted file mode 100644 index c21523e09..000000000 --- a/tests/integration/rules/boolType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::boolType()->assert('teste')); -exceptionMessage(static fn() => v::not(v::boolType())->assert(true)); -exceptionFullMessage(static fn() => v::boolType()->assert([])); -exceptionFullMessage(static fn() => v::not(v::boolType())->assert(false)); -?> ---EXPECT-- -"teste" must be a boolean -`true` must not be a boolean -- `[]` must be a boolean -- `false` must not be a boolean \ No newline at end of file diff --git a/tests/integration/rules/boolVal.phpt b/tests/integration/rules/boolVal.phpt deleted file mode 100644 index 7fd74ca07..000000000 --- a/tests/integration/rules/boolVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::boolVal()->assert('ok')); -exceptionMessage(static fn() => v::not(v::boolVal())->assert('yes')); -exceptionFullMessage(static fn() => v::boolVal()->assert('yep')); -exceptionFullMessage(static fn() => v::not(v::boolVal())->assert('on')); -?> ---EXPECT-- -"ok" must be a boolean value -"yes" must not be a boolean value -- "yep" must be a boolean value -- "on" must not be a boolean value diff --git a/tests/integration/rules/bsn.phpt b/tests/integration/rules/bsn.phpt deleted file mode 100644 index fdf7690fb..000000000 --- a/tests/integration/rules/bsn.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::bsn()->assert('acb')); -exceptionMessage(static fn() => v::not(v::bsn())->assert('612890053')); -exceptionFullMessage(static fn() => v::bsn()->assert('abc')); -exceptionFullMessage(static fn() => v::not(v::bsn())->assert('612890053')); -?> ---EXPECT-- -"acb" must be a valid BSN -"612890053" must not be a valid BSN -- "abc" must be a valid BSN -- "612890053" must not be a valid BSN \ No newline at end of file diff --git a/tests/integration/rules/call.phpt b/tests/integration/rules/call.phpt deleted file mode 100644 index 19e52c581..000000000 --- a/tests/integration/rules/call.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - v::call('trim', v::noWhitespace())->assert(' two words ')); -exceptionMessage(static fn() => v::not(v::call('stripslashes', v::stringType()))->assert(' some\\thing ')); -exceptionMessage(static fn() => v::call('stripslashes', v::alwaysValid())->assert([])); -exceptionFullMessage(static fn() => v::call('strval', v::intType())->assert(1234)); -exceptionFullMessage(static fn() => v::not(v::call('is_float', v::boolType()))->assert(1.2)); -exceptionFullMessage(static fn() => v::call('array_shift', v::alwaysValid())->assert(INF)); -?> ---EXPECT-- -"two words" must not contain whitespaces -" something " must not be a string -`[]` must be a suitable argument for `stripslashes(string $string): string` -- "1234" must be an integer -- `true` must not be a boolean -- `INF` must be a suitable argument for `array_shift(array &$array): ?mixed` \ No newline at end of file diff --git a/tests/integration/rules/callableType.phpt b/tests/integration/rules/callableType.phpt deleted file mode 100644 index 9e6b8f655..000000000 --- a/tests/integration/rules/callableType.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---FILE-- - v::callableType()->assert([])); -exceptionMessage(static fn() => v::not(v::callableType())->assert('trim')); -exceptionFullMessage(static fn() => v::callableType()->assert(true)); -exceptionFullMessage(static fn() => v::not(v::callableType())->assert(static function (): void { - // Do nothing -})); -?> ---EXPECT-- -`[]` must be a callable -`trim(string $string, string $characters = " \n\r\t\u000b\u0000"): string` must not be a callable -- `true` must be a callable -- `function (): void` must not be a callable \ No newline at end of file diff --git a/tests/integration/rules/callback.phpt b/tests/integration/rules/callback.phpt deleted file mode 100644 index 17e8305c0..000000000 --- a/tests/integration/rules/callback.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::callback('is_string')->assert([])); -exceptionMessage(static fn() => v::not(v::callback('is_string'))->assert('foo')); -exceptionFullMessage(static fn() => v::callback('is_string')->assert(true)); -exceptionFullMessage(static fn() => v::not(v::callback('is_string'))->assert('foo')); -?> ---EXPECT-- -`[]` must be valid -"foo" must be invalid -- `true` must be valid -- "foo" must be invalid \ No newline at end of file diff --git a/tests/integration/rules/charset.phpt b/tests/integration/rules/charset.phpt deleted file mode 100644 index 2ea9833fe..000000000 --- a/tests/integration/rules/charset.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::charset('ASCII')->assert('açaí')); -exceptionMessage(static fn() => v::not(v::charset('UTF-8'))->assert('açaí')); -exceptionFullMessage(static fn() => v::charset('ASCII')->assert('açaí')); -exceptionFullMessage(static fn() => v::not(v::charset('UTF-8'))->assert('açaí')); -?> ---EXPECT-- -"açaí" must only contain characters from the `["ASCII"]` charset -"açaí" must not contain any characters from the `["UTF-8"]` charset -- "açaí" must only contain characters from the `["ASCII"]` charset -- "açaí" must not contain any characters from the `["UTF-8"]` charset \ No newline at end of file diff --git a/tests/integration/rules/cnh.phpt b/tests/integration/rules/cnh.phpt deleted file mode 100644 index ae9700417..000000000 --- a/tests/integration/rules/cnh.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::cnh()->assert('batman')); -exceptionMessage(static fn() => v::not(v::cnh())->assert('02650306461')); -exceptionFullMessage(static fn() => v::cnh()->assert('bruce wayne')); -exceptionFullMessage(static fn() => v::not(v::cnh())->assert('02650306461')); -?> ---EXPECT-- -"batman" must be a valid CNH number -"02650306461" must not be a valid CNH number -- "bruce wayne" must be a valid CNH number -- "02650306461" must not be a valid CNH number diff --git a/tests/integration/rules/cnpj.phpt b/tests/integration/rules/cnpj.phpt deleted file mode 100644 index 1dead9770..000000000 --- a/tests/integration/rules/cnpj.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::cnpj()->assert('não cnpj')); -exceptionMessage(static fn() => v::not(v::cnpj())->assert('65.150.175/0001-20')); -exceptionFullMessage(static fn() => v::cnpj()->assert('test')); -exceptionFullMessage(static fn() => v::not(v::cnpj())->assert('65.150.175/0001-20')); -?> ---EXPECT-- -"não cnpj" must be a valid CNPJ number -"65.150.175/0001-20" must not be a valid CNPJ number -- "test" must be a valid CNPJ number -- "65.150.175/0001-20" must not be a valid CNPJ number diff --git a/tests/integration/rules/cntrl.phpt b/tests/integration/rules/cntrl.phpt deleted file mode 100644 index f9d2c6886..000000000 --- a/tests/integration/rules/cntrl.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::control()->assert('16-50')); -exceptionMessage(static fn() => v::control('16')->assert('16-50')); -exceptionMessage(static fn() => v::not(v::control())->assert("\n")); -exceptionMessage(static fn() => v::not(v::control('16'))->assert("16\n")); -exceptionFullMessage(static fn() => v::control()->assert('Foo')); -exceptionFullMessage(static fn() => v::control('Bar')->assert('Foo')); -exceptionFullMessage(static fn() => v::not(v::control())->assert("\n")); -exceptionFullMessage(static fn() => v::not(v::control('Bar'))->assert("Bar\n")); -?> ---EXPECT-- -"16-50" must only contain control characters -"16-50" must only contain control characters and "16" -"\n" must not contain control characters -"16\n" must not contain control characters or "16" -- "Foo" must only contain control characters -- "Foo" must only contain control characters and "Bar" -- "\n" must not contain control characters -- "Bar\n" must not contain control characters or "Bar" \ No newline at end of file diff --git a/tests/integration/rules/consecutive.phpt b/tests/integration/rules/consecutive.phpt deleted file mode 100644 index 1d4fc0f50..000000000 --- a/tests/integration/rules/consecutive.phpt +++ /dev/null @@ -1,139 +0,0 @@ ---FILE-- - [v::consecutive(v::alwaysValid(), v::trueVal()), false], - 'Inverted' => [v::not(v::consecutive(v::alwaysValid(), v::trueVal())), true], - 'Default with inverted failing rule' => [v::consecutive(v::alwaysValid(), v::not(v::trueVal())), true], - 'With wrapped name, default' => [ - v::consecutive(v::alwaysValid(), v::trueVal()->setName('Wrapped'))->setName('Wrapper'), - false, - ], - 'With wrapper name, default' => [ - v::consecutive(v::alwaysValid(), v::trueVal())->setName('Wrapper'), - false, - ], - 'With the name set in the wrapped rule of an inverted failing rule' => [ - v::consecutive(v::alwaysValid(), v::not(v::trueVal()->setName('Wrapped'))->setName('Not'))->setName('Wrapper'), - true, - ], - 'With the name set in an inverted failing rule' => [ - v::consecutive(v::alwaysValid(), v::not(v::trueVal())->setName('Not'))->setName('Wrapper'), - true, - ], - 'With the name set in the "consecutive" that has an inverted failing rule' => [ - v::consecutive(v::alwaysValid(), v::not(v::trueVal()))->setName('Wrapper'), - true, - ], - 'With template' => [ - v::consecutive(v::alwaysValid(), v::trueVal()), - false, - 'Consecutive cool cats cunningly continuous cookies', - ], - 'With multiple templates' => [ - v::consecutive(v::alwaysValid(), v::trueVal()), - false, - ['trueVal' => 'Clever clowns craft consecutive clever clocks'], - ], - 'Real example' => [ - v::consecutive( - v::key('countyCode', v::countryCode()), - v::lazy(static fn($input) => v::key('subdivisionCode', v::subdivisionCode($input['countyCode']))), - ), - [ - 'countyCode' => 'BR', - 'subdivisionCode' => 'CA', - ], - ], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -`false` must evaluate to `true` -- `false` must evaluate to `true` -[ - 'trueVal' => '`false` must evaluate to `true`', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -`true` must not evaluate to `true` -- `true` must not evaluate to `true` -[ - 'notTrueVal' => '`true` must not evaluate to `true`', -] - -Default with inverted failing rule -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -`true` must not evaluate to `true` -- `true` must not evaluate to `true` -[ - 'notTrueVal' => '`true` must not evaluate to `true`', -] - -With wrapped name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must evaluate to `true` -- Wrapped must evaluate to `true` -[ - 'trueVal' => 'Wrapped must evaluate to `true`', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must evaluate to `true` -- Wrapper must evaluate to `true` -[ - 'trueVal' => 'Wrapper must evaluate to `true`', -] - -With the name set in the wrapped rule of an inverted failing rule -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not evaluate to `true` -- Wrapped must not evaluate to `true` -[ - 'notTrueVal' => 'Wrapped must not evaluate to `true`', -] - -With the name set in an inverted failing rule -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not must not evaluate to `true` -- Not must not evaluate to `true` -[ - 'notTrueVal' => 'Not must not evaluate to `true`', -] - -With the name set in the "consecutive" that has an inverted failing rule -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must not evaluate to `true` -- Wrapper must not evaluate to `true` -[ - 'notTrueVal' => 'Wrapper must not evaluate to `true`', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Consecutive cool cats cunningly continuous cookies -- Consecutive cool cats cunningly continuous cookies -[ - 'trueVal' => 'Consecutive cool cats cunningly continuous cookies', -] - -With multiple templates -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Clever clowns craft consecutive clever clocks -- Clever clowns craft consecutive clever clocks -[ - 'trueVal' => 'Clever clowns craft consecutive clever clocks', -] - -Real example -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -subdivisionCode must be a subdivision code of Brazil -- subdivisionCode must be a subdivision code of Brazil -[ - 'subdivisionCode' => 'subdivisionCode must be a subdivision code of Brazil', -] diff --git a/tests/integration/rules/consonant.phpt b/tests/integration/rules/consonant.phpt deleted file mode 100644 index 06fedeac5..000000000 --- a/tests/integration/rules/consonant.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::consonant()->assert('aeiou')); -exceptionMessage(static fn() => v::consonant('d')->assert('daeiou')); -exceptionMessage(static fn() => v::not(v::consonant())->assert('bcd')); -exceptionMessage(static fn() => v::not(v::consonant('a'))->assert('abcd')); -exceptionFullMessage(static fn() => v::consonant()->assert('aeiou')); -exceptionFullMessage(static fn() => v::consonant('d')->assert('daeiou')); -exceptionFullMessage(static fn() => v::not(v::consonant())->assert('bcd')); -exceptionFullMessage(static fn() => v::not(v::consonant('a'))->assert('abcd')); -?> ---EXPECT-- -"aeiou" must only contain consonants -"daeiou" must only contain consonants and "d" -"bcd" must not contain consonants -"abcd" must not contain consonants or "a" -- "aeiou" must only contain consonants -- "daeiou" must only contain consonants and "d" -- "bcd" must not contain consonants -- "abcd" must not contain consonants or "a" \ No newline at end of file diff --git a/tests/integration/rules/contains.phpt b/tests/integration/rules/contains.phpt deleted file mode 100644 index 81b337c69..000000000 --- a/tests/integration/rules/contains.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::contains('foo')->assert('bar')); -exceptionMessage(static fn() => v::not(v::contains('foo'))->assert('fool')); -exceptionFullMessage(static fn() => v::contains('foo')->assert(['bar'])); -exceptionFullMessage(static fn() => v::not(v::contains('foo', true))->assert(['bar', 'foo'])); -?> ---EXPECT-- -"bar" must contain "foo" -"fool" must not contain "foo" -- `["bar"]` must contain "foo" -- `["bar", "foo"]` must not contain "foo" \ No newline at end of file diff --git a/tests/integration/rules/containsAny.phpt b/tests/integration/rules/containsAny.phpt deleted file mode 100644 index afd5f4177..000000000 --- a/tests/integration/rules/containsAny.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::containsAny(['foo', 'bar'])->assert('baz')); -exceptionMessage(static fn() => v::not(v::containsAny(['foo', 'bar']))->assert('fool')); -exceptionFullMessage(static fn() => v::containsAny(['foo', 'bar'])->assert(['baz'])); -exceptionFullMessage(static fn() => v::not(v::containsAny(['foo', 'bar'], true))->assert(['bar', 'foo'])); -?> ---EXPECT-- -"baz" must contain at least one value from `["foo", "bar"]` -"fool" must not contain any value from `["foo", "bar"]` -- `["baz"]` must contain at least one value from `["foo", "bar"]` -- `["bar", "foo"]` must not contain any value from `["foo", "bar"]` \ No newline at end of file diff --git a/tests/integration/rules/countable.phpt b/tests/integration/rules/countable.phpt deleted file mode 100644 index be27edfc2..000000000 --- a/tests/integration/rules/countable.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::countable()->assert(1.0)); -exceptionMessage(static fn() => v::not(v::countable())->assert([])); -exceptionFullMessage(static fn() => v::countable()->assert('Not countable!')); -exceptionFullMessage(static fn() => v::not(v::countable())->assert(new ArrayObject())); -?> ---EXPECT-- -1.0 must be a countable value -`[]` must not be a countable value -- "Not countable!" must be a countable value -- `ArrayObject { getArrayCopy() => [] }` must not be a countable value \ No newline at end of file diff --git a/tests/integration/rules/countryCode.phpt b/tests/integration/rules/countryCode.phpt deleted file mode 100644 index 25d1f8065..000000000 --- a/tests/integration/rules/countryCode.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::countryCode()->assert('1')); -exceptionMessage(static fn() => v::not(v::countryCode())->assert('BR')); -exceptionFullMessage(static fn() => v::countryCode()->assert('1')); -exceptionFullMessage(static fn() => v::not(v::countryCode())->assert('BR')); -?> ---EXPECT-- -"1" must be a valid country code -"BR" must not be a valid country code -- "1" must be a valid country code -- "BR" must not be a valid country code \ No newline at end of file diff --git a/tests/integration/rules/cpf.phpt b/tests/integration/rules/cpf.phpt deleted file mode 100644 index 8927f50ee..000000000 --- a/tests/integration/rules/cpf.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::cpf()->assert('this thing')); -exceptionMessage(static fn() => v::not(v::cpf())->assert('276.865.775-11')); -exceptionFullMessage(static fn() => v::cpf()->assert('your mother')); -exceptionFullMessage(static fn() => v::not(v::cpf())->assert('61836182848')); -?> ---EXPECT-- -"this thing" must be a valid CPF number -"276.865.775-11" must not be a valid CPF number -- "your mother" must be a valid CPF number -- "61836182848" must not be a valid CPF number diff --git a/tests/integration/rules/creditCard.phpt b/tests/integration/rules/creditCard.phpt deleted file mode 100644 index d367b915f..000000000 --- a/tests/integration/rules/creditCard.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::creditCard('Discover')->assert(3566002020360505)); -exceptionMessage(static fn() => v::not(v::creditCard('Visa'))->assert(4024007153361885)); -exceptionFullMessage(static fn() => v::creditCard('MasterCard')->assert(3566002020360505)); -exceptionFullMessage(static fn() => v::not(v::creditCard())->assert(5555444433331111)); -?> ---EXPECT-- -3566002020360505 must be a valid Discover credit card number -4024007153361885 must not be a valid Visa credit card number -- 3566002020360505 must be a valid MasterCard credit card number -- 5555444433331111 must not be a valid credit card number diff --git a/tests/integration/rules/currencyCode.phpt b/tests/integration/rules/currencyCode.phpt deleted file mode 100644 index 6c6ee36fd..000000000 --- a/tests/integration/rules/currencyCode.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::currencyCode()->assert('batman')); -exceptionMessage(static fn() => v::not(v::currencyCode())->assert('BRL')); -exceptionFullMessage(static fn() => v::currencyCode()->assert('ppz')); -exceptionFullMessage(static fn() => v::not(v::currencyCode())->assert('GBP')); -?> ---EXPECT-- -"batman" must be a valid currency code -"BRL" must not be a valid currency code -- "ppz" must be a valid currency code -- "GBP" must not be a valid currency code \ No newline at end of file diff --git a/tests/integration/rules/date.phpt b/tests/integration/rules/date.phpt deleted file mode 100644 index 2561363fd..000000000 --- a/tests/integration/rules/date.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---FILE-- - v::date()->assert('2018-01-29T08:32:54+00:00')); -exceptionMessage(static fn() => v::not(v::date())->assert('2018-01-29')); -exceptionFullMessage(static fn() => v::date()->assert('2018-01-29T08:32:54+00:00')); -exceptionFullMessage(static fn() => v::not(v::date('d/m/Y'))->assert('29/01/2018')); -?> ---EXPECT-- -"2018-01-29T08:32:54+00:00" must be a valid date in the format "2005-12-30" -"2018-01-29" must not be a valid date in the format "2005-12-30" -- "2018-01-29T08:32:54+00:00" must be a valid date in the format "2005-12-30" -- "29/01/2018" must not be a valid date in the format "30/12/2005" diff --git a/tests/integration/rules/dateTime.phpt b/tests/integration/rules/dateTime.phpt deleted file mode 100644 index 4981bc21e..000000000 --- a/tests/integration/rules/dateTime.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---FILE-- - v::dateTime()->assert('FooBarBazz')); -exceptionMessage(static fn() => v::dateTime('c')->assert('06-12-1995')); -exceptionFullMessage(static fn() => v::dateTime()->assert('QuxQuuxx')); -exceptionFullMessage(static fn() => v::dateTime('r')->assert(2018013030)); -exceptionMessage(static fn() => v::not(v::dateTime())->assert('4 days ago')); -exceptionMessage(static fn() => v::not(v::dateTime('Y-m-d'))->assert('1988-09-09')); -exceptionFullMessage(static fn() => v::not(v::dateTime())->assert('+3 weeks')); -exceptionFullMessage(static fn() => v::not(v::dateTime('d/m/y'))->assert('23/07/99')); -?> ---EXPECT-- -"FooBarBazz" must be a valid date/time -"06-12-1995" must be a valid date/time in the format "2005-12-30T01:02:03+00:00" -- "QuxQuuxx" must be a valid date/time -- 2018013030 must be a valid date/time in the format "Fri, 30 Dec 2005 01:02:03 +0000" -"4 days ago" must not be a valid date/time -"1988-09-09" must not be a valid date/time in the format "2005-12-30" -- "+3 weeks" must not be a valid date/time -- "23/07/99" must not be a valid date/time in the format "30/12/05" diff --git a/tests/integration/rules/dateTimeDiff.phpt b/tests/integration/rules/dateTimeDiff.phpt deleted file mode 100644 index 7048353d5..000000000 --- a/tests/integration/rules/dateTimeDiff.phpt +++ /dev/null @@ -1,189 +0,0 @@ ---FILE-- - [v::dateTimeDiff('years', v::equals(2)), '1 year ago'], - 'With $type = "months"' => [v::dateTimeDiff('months', v::equals(3)), '2 months ago'], - 'With $type = "days"' => [v::dateTimeDiff('days', v::equals(4)), '3 days ago'], - 'With $type = "hours"' => [v::dateTimeDiff('hours', v::equals(5)), '4 hours ago'], - 'With $type = "minutes"' => [v::dateTimeDiff('minutes', v::equals(6)), '5 minutes ago'], - 'With $type = "microseconds"' => [v::dateTimeDiff('microseconds', v::equals(7)), '6 microseconds ago'], - 'With custom $format' => [v::dateTimeDiff('years', v::lessThan(8), 'd/m/Y'), '09/12/1988'], - 'With input in non-parseable date' => [v::dateTimeDiff('years', v::equals(2)), 'not a date'], - 'With input in incorrect $format' => [v::dateTimeDiff('years', v::equals(2), 'Y-m-d'), '1 year ago'], - 'With custom $now' => [v::dateTimeDiff('years', v::lessThan(9), null, new DateTimeImmutable()), '09/12/1988'], - 'With custom template' => [v::dateTimeDiff('years', v::equals(2)->setTemplate('Custom template')), '1 year ago'], - 'Wrapped by "not"' => [v::not(v::dateTimeDiff('years', v::lessThan(8))), '7 year ago'], - 'Wrapping "not"' => [v::dateTimeDiff('years', v::not(v::lessThan(9))), '8 year ago'], - 'Wrapped with custom template' => [ - v::dateTimeDiff('years', v::equals(2)->setTemplate('Wrapped with custom template')), - '1 year ago', - ], - 'Wrapper with custom template' => [ - v::dateTimeDiff('years', v::equals(2))->setTemplate('Wrapper with custom template'), - '1 year ago', - ], - 'Without subsequent result' => [ - v::dateTimeDiff('years', v::primeNumber()->between(2, 5)), - '1 year ago', - ], - 'Without subsequent result with templates' => [ - v::dateTimeDiff('years', v::primeNumber()->between(2, 5)), - '1 year ago', - [ - 'dateTimeDiff' => [ - 'primeNumber' => 'Interval must be a valid prime number', - 'between' => 'Interval must be between 2 and 5', - ], - ], - ], -]); -?> ---EXPECTF-- -With $type = "years" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between now and 1 year ago must be equal to 2 -- The number of years between now and 1 year ago must be equal to 2 -[ - 'dateTimeDiffEquals' => 'The number of years between now and 1 year ago must be equal to 2', -] - -With $type = "months" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of months between now and 2 months ago must be equal to 3 -- The number of months between now and 2 months ago must be equal to 3 -[ - 'dateTimeDiffEquals' => 'The number of months between now and 2 months ago must be equal to 3', -] - -With $type = "days" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of days between now and 3 days ago must be equal to 4 -- The number of days between now and 3 days ago must be equal to 4 -[ - 'dateTimeDiffEquals' => 'The number of days between now and 3 days ago must be equal to 4', -] - -With $type = "hours" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of hours between now and 4 hours ago must be equal to 5 -- The number of hours between now and 4 hours ago must be equal to 5 -[ - 'dateTimeDiffEquals' => 'The number of hours between now and 4 hours ago must be equal to 5', -] - -With $type = "minutes" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of minutes between now and 5 minutes ago must be equal to 6 -- The number of minutes between now and 5 minutes ago must be equal to 6 -[ - 'dateTimeDiffEquals' => 'The number of minutes between now and 5 minutes ago must be equal to 6', -] - -With $type = "microseconds" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of microseconds between now and 6 microseconds ago must be equal to 7 -- The number of microseconds between now and 6 microseconds ago must be equal to 7 -[ - 'dateTimeDiffEquals' => 'The number of microseconds between now and 6 microseconds ago must be equal to 7', -] - -With custom $format -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between %d/%d/%d and %d/%d/%d must be less than 8 -- The number of years between %d/%d/%d and %d/%d/%d must be less than 8 -[ - 'dateTimeDiffLessThan' => 'The number of years between %d/%d/%d and %d/%d/%d must be less than 8', -] - -With input in non-parseable date -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -For comparison with now, "not a date" must be a valid datetime -- For comparison with now, "not a date" must be a valid datetime -[ - 'dateTimeDiffEquals' => 'For comparison with now, "not a date" must be a valid datetime', -] - -With input in incorrect $format -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -For comparison with %d-%d-%d, "1 year ago" must be a valid datetime in the format %d-%d-%d -- For comparison with %d-%d-%d, "1 year ago" must be a valid datetime in the format %d-%d-%d -[ - 'dateTimeDiffEquals' => 'For comparison with %d-%d-%d, "1 year ago" must be a valid datetime in the format %d-%d-%d', -] - -With custom $now -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between %d-%d-%d %d:%d:%d.%d and %d/%d/%d must be less than 9 -- The number of years between %d-%d-%d %d:%d:%d.%d and %d/%d/%d must be less than 9 -[ - 'dateTimeDiffLessThan' => 'The number of years between %d-%d-%d %d:%d:%d.%d and %d/%d/%d must be less than 9', -] - -With custom template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Custom template -- Custom template -[ - 'equals' => 'Custom template', -] - -Wrapped by "not" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between now and 7 year ago must not be less than 8 -- The number of years between now and 7 year ago must not be less than 8 -[ - 'notDateTimeDiffLessThan' => 'The number of years between now and 7 year ago must not be less than 8', -] - -Wrapping "not" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between now and 8 year ago must not be less than 9 -- The number of years between now and 8 year ago must not be less than 9 -[ - 'dateTimeDiffNotLessThan' => 'The number of years between now and 8 year ago must not be less than 9', -] - -Wrapped with custom template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped with custom template -- Wrapped with custom template -[ - 'equals' => 'Wrapped with custom template', -] - -Wrapper with custom template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper with custom template -- Wrapper with custom template -[ - 'dateTimeDiffEquals' => 'Wrapper with custom template', -] - -Without subsequent result -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between now and 1 year ago must be a prime number -- All of the required rules must pass for 1 year ago - - 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 between 2 and 5 -[ - '__root__' => 'All of the required rules must pass for 1 year ago', - 'dateTimeDiffPrimeNumber' => 'The number of years between now and 1 year ago must be a prime number', - 'dateTimeDiffBetween' => 'The number of years between now and 1 year ago must be between 2 and 5', -] - -Without subsequent result with templates -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The number of years between now and 1 year ago must be a prime number -- All of the required rules must pass for 1 year ago - - 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 between 2 and 5 -[ - '__root__' => 'All of the required rules must pass for 1 year ago', - 'dateTimeDiffPrimeNumber' => 'The number of years between now and 1 year ago must be a prime number', - 'dateTimeDiffBetween' => 'The number of years between now and 1 year ago must be between 2 and 5', -] diff --git a/tests/integration/rules/decimal.phpt b/tests/integration/rules/decimal.phpt deleted file mode 100644 index d2110c036..000000000 --- a/tests/integration/rules/decimal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::decimal(3)->assert(0.1234)); -exceptionFullMessage(static fn() => v::decimal(2)->assert(0.123)); -exceptionMessage(static fn() => v::not(v::decimal(5))->assert(0.12345)); -exceptionFullMessage(static fn() => v::not(v::decimal(2))->assert(0.34)); -?> ---EXPECT-- -0.1234 must have 3 decimals -- 0.123 must have 2 decimals -0.12345 must not have 5 decimals -- 0.34 must not have 2 decimals diff --git a/tests/integration/rules/digit.phpt b/tests/integration/rules/digit.phpt deleted file mode 100644 index 3b0cdef3c..000000000 --- a/tests/integration/rules/digit.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::digit()->assert('abc')); -exceptionMessage(static fn() => v::digit('-')->assert('a-b')); -exceptionMessage(static fn() => v::not(v::digit())->assert('123')); -exceptionMessage(static fn() => v::not(v::digit('-'))->assert('1-3')); -exceptionFullMessage(static fn() => v::digit()->assert('abc')); -exceptionFullMessage(static fn() => v::digit('-')->assert('a-b')); -exceptionFullMessage(static fn() => v::not(v::digit())->assert('123')); -exceptionFullMessage(static fn() => v::not(v::digit('-'))->assert('1-3')); -?> ---EXPECT-- -"abc" must contain only digits (0-9) -"a-b" must contain only digits (0-9) and "-" -"123" must not contain digits (0-9) -"1-3" must not contain digits (0-9) and "-" -- "abc" must contain only digits (0-9) -- "a-b" must contain only digits (0-9) and "-" -- "123" must not contain digits (0-9) -- "1-3" must not contain digits (0-9) and "-" diff --git a/tests/integration/rules/directory.phpt b/tests/integration/rules/directory.phpt deleted file mode 100644 index c4d0a8fdb..000000000 --- a/tests/integration/rules/directory.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::directory()->assert('batman')); -exceptionMessage(static fn() => v::not(v::directory())->assert(dirname('/etc/'))); -exceptionFullMessage(static fn() => v::directory()->assert('ppz')); -exceptionFullMessage(static fn() => v::not(v::directory())->assert(dirname('/etc/'))); -?> ---EXPECT-- -"batman" must be a directory -"/" must not be a directory -- "ppz" must be a directory -- "/" must not be a directory diff --git a/tests/integration/rules/domain.phpt b/tests/integration/rules/domain.phpt deleted file mode 100644 index 351f3c8ad..000000000 --- a/tests/integration/rules/domain.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::domain()->assert('batman')); -exceptionMessage(static fn() => v::not(v::domain())->assert('r--w.com')); -exceptionFullMessage(static fn() => v::domain()->assert('p-éz-.kk')); -exceptionFullMessage(static fn() => v::not(v::domain())->assert('github.com')); -?> ---EXPECT-- -"batman" must be a valid domain -"r--w.com" must not be a valid domain -- "p-éz-.kk" must be a valid domain -- "github.com" must not be a valid domain diff --git a/tests/integration/rules/each.phpt b/tests/integration/rules/each.phpt deleted file mode 100644 index 179c2cdb4..000000000 --- a/tests/integration/rules/each.phpt +++ /dev/null @@ -1,256 +0,0 @@ ---FILE-- - [v::each(v::intType()), $nonIterable], - 'Empty' => [v::each(v::intType()), $empty], - 'Default' => [v::each(v::intType()), $default], - 'Inverted' => [v::not(v::each(v::intType())), $inverted], - - // With name - 'With name, non-iterable' => [v::each(v::intType()->setName('Wrapped'))->setName('Wrapper'), $nonIterable], - 'With name, empty' => [v::each(v::intType()->setName('Wrapped'))->setName('Wrapper'), $empty], - 'With name, default' => [v::each(v::intType()->setName('Wrapped'))->setName('Wrapper'), $default], - 'With name, inverted' => [ - v::not(v::each(v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not'), - $inverted, - ], - 'With wrapper name, default' => [v::each(v::intType())->setName('Wrapper'), $default], - 'With wrapper name, inverted' => [ - v::not(v::each(v::intType())->setName('Wrapper'))->setName('Not'), - $inverted, - ], - 'With Not name, inverted' => [ - v::not(v::each(v::intType()))->setName('Not'), - $inverted, - ], - - // With template - 'With template, non-iterable' => [v::each(v::intType()), $nonIterable, 'You should have passed an iterable'], - 'With template, empty' => [v::each(v::intType()), $empty, 'You should have passed an non-empty'], - 'With template, default' => [v::each(v::intType()), $default, 'All items should have been integers'], - 'with template, inverted' => [v::not(v::each(v::intType())), $inverted, 'All items should not have been integers'], - - // With array template - 'With array template, default' => [ - v::each(v::intType()), - $default, [ - 'each' => [ - '__root__' => 'Here a sequence of items that did not pass the validation', - 'intType.1' => 'First item should have been an integer', - 'intType.2' => 'Second item should have been an integer', - 'intType.3' => 'Third item should have been an integer', - ], - ], - ], - 'With array template and name, default' => [ - v::each(v::intType()->setName('Wrapped'))->setName('Wrapper'), - $default, [ - 'Wrapped' => [ - '__root__' => 'Here a sequence of items that did not pass the validation', - 'Wrapped.1' => 'First item should have been an integer', - 'Wrapped.2' => 'Second item should have been an integer', - 'Wrapped.3' => 'Third item should have been an integer', - ], - ], - ], -]); -?> ---EXPECT-- -Non-iterable -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -`null` must be iterable -- `null` must be iterable -[ - 'each' => '`null` must be iterable', -] - -Empty -⎺⎺⎺⎺⎺ -The value must not be empty -- The value must not be empty -[ - 'each' => 'The value must not be empty', -] - -Default -⎺⎺⎺⎺⎺⎺⎺ -"a" must be an integer -- Each item in `["a", "b", "c"]` must be valid - - "a" must be an integer - - "b" must be an integer - - "c" must be an integer -[ - '__root__' => 'Each item in `["a", "b", "c"]` must be valid', - 'intType.1' => '"a" must be an integer', - 'intType.2' => '"b" must be an integer', - 'intType.3' => '"c" must be an integer', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -1 must not be an integer -- Each item in `[1, 2, 3]` must be invalid - - 1 must not be an integer - - 2 must not be an integer - - 3 must not be an integer -[ - '__root__' => 'Each item in `[1, 2, 3]` must be invalid', - 'intType.1' => '1 must not be an integer', - 'intType.2' => '2 must not be an integer', - 'intType.3' => '3 must not be an integer', -] - -With name, non-iterable -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be iterable -- Wrapped must be iterable -[ - 'Wrapped' => 'Wrapped must be iterable', -] - -With name, empty -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be empty -- Wrapped must not be empty -[ - 'Wrapped' => 'Wrapped must not be empty', -] - -With name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be an integer -- Each item in Wrapped must be valid - - Wrapped must be an integer - - Wrapped must be an integer - - Wrapped must be an integer -[ - '__root__' => 'Each item in Wrapped must be valid', - 'intType.1' => 'Wrapped must be an integer', - 'intType.2' => 'Wrapped must be an integer', - 'intType.3' => 'Wrapped must be an integer', -] - -With name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be an integer -- Each item in Wrapped must be invalid - - Wrapped must not be an integer - - Wrapped must not be an integer - - Wrapped must not be an integer -[ - '__root__' => 'Each item in Wrapped must be invalid', - 'intType.1' => 'Wrapped must not be an integer', - 'intType.2' => 'Wrapped must not be an integer', - 'intType.3' => 'Wrapped must not be an integer', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must be an integer -- Each item in Wrapper must be valid - - Wrapper must be an integer - - Wrapper must be an integer - - Wrapper must be an integer -[ - '__root__' => 'Each item in Wrapper must be valid', - 'intType.1' => 'Wrapper must be an integer', - 'intType.2' => 'Wrapper must be an integer', - 'intType.3' => 'Wrapper must be an integer', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must not be an integer -- Each item in Wrapper must be invalid - - Wrapper must not be an integer - - Wrapper must not be an integer - - Wrapper must not be an integer -[ - '__root__' => 'Each item in Wrapper must be invalid', - 'intType.1' => 'Wrapper must not be an integer', - 'intType.2' => 'Wrapper must not be an integer', - 'intType.3' => 'Wrapper must not be an integer', -] - -With Not name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not must not be an integer -- Each item in Not must be invalid - - Not must not be an integer - - Not must not be an integer - - Not must not be an integer -[ - '__root__' => 'Each item in Not must be invalid', - 'intType.1' => 'Not must not be an integer', - 'intType.2' => 'Not must not be an integer', - 'intType.3' => 'Not must not be an integer', -] - -With template, non-iterable -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -You should have passed an iterable -- You should have passed an iterable -[ - 'each' => 'You should have passed an iterable', -] - -With template, empty -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -You should have passed an non-empty -- You should have passed an non-empty -[ - 'each' => 'You should have passed an non-empty', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -All items should have been integers -- All items should have been integers -[ - 'each' => 'All items should have been integers', -] - -with template, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -All items should not have been integers -- All items should not have been integers -[ - 'notEach' => 'All items should not have been integers', -] - -With array template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -First item should have been an integer -- Here a sequence of items that did not pass the validation - - First item should have been an integer - - Second item should have been an integer - - Third item should have been an integer -[ - '__root__' => 'Here a sequence of items that did not pass the validation', - 'intType.1' => 'First item should have been an integer', - 'intType.2' => 'Second item should have been an integer', - 'intType.3' => 'Third item should have been an integer', -] - -With array template and name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be an integer -- Each item in Wrapped must be valid - - Wrapped must be an integer - - Wrapped must be an integer - - Wrapped must be an integer -[ - '__root__' => 'Each item in Wrapped must be valid', - 'intType.1' => 'Wrapped must be an integer', - 'intType.2' => 'Wrapped must be an integer', - 'intType.3' => 'Wrapped must be an integer', -] diff --git a/tests/integration/rules/email.phpt b/tests/integration/rules/email.phpt deleted file mode 100644 index f2e6552d3..000000000 --- a/tests/integration/rules/email.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::email()->assert('batman')); -exceptionMessage(static fn() => v::not(v::email())->assert('bruce.wayne@gothancity.com')); -exceptionFullMessage(static fn() => v::email()->assert('bruce wayne')); -exceptionFullMessage(static fn() => v::not(v::email())->assert('iambatman@gothancity.com')); -?> ---EXPECT-- -"batman" must be a valid email address -"bruce.wayne@gothancity.com" must not be an email address -- "bruce wayne" must be a valid email address -- "iambatman@gothancity.com" must not be an email address \ No newline at end of file diff --git a/tests/integration/rules/endsWith.phpt b/tests/integration/rules/endsWith.phpt deleted file mode 100644 index 92d8d452d..000000000 --- a/tests/integration/rules/endsWith.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::endsWith('foo')->assert('bar')); -exceptionMessage(static fn() => v::not(v::endsWith('foo'))->assert(['bar', 'foo'])); -exceptionFullMessage(static fn() => v::endsWith('foo')->assert('')); -exceptionFullMessage(static fn() => v::not(v::endsWith('foo'))->assert(['bar', 'foo'])); -?> ---EXPECT-- -"bar" must end with "foo" -`["bar", "foo"]` must not end with "foo" -- "" must end with "foo" -- `["bar", "foo"]` must not end with "foo" diff --git a/tests/integration/rules/equals.phpt b/tests/integration/rules/equals.phpt deleted file mode 100644 index 8da4cc83a..000000000 --- a/tests/integration/rules/equals.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::equals(123)->assert(321)); -exceptionMessage(static fn() => v::not(v::equals(321))->assert(321)); -exceptionFullMessage(static fn() => v::equals(123)->assert(321)); -exceptionFullMessage(static fn() => v::not(v::equals(321))->assert(321)); -?> ---EXPECT-- -321 must be equal to 123 -321 must not be equal to 321 -- 321 must be equal to 123 -- 321 must not be equal to 321 \ No newline at end of file diff --git a/tests/integration/rules/equivalent.phpt b/tests/integration/rules/equivalent.phpt deleted file mode 100644 index 5e1a628be..000000000 --- a/tests/integration/rules/equivalent.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::equivalent(true)->assert(false)); -exceptionMessage(static fn() => v::not(v::equivalent('Something'))->assert('someThing')); -exceptionFullMessage(static fn() => v::equivalent(123)->assert('true')); -exceptionFullMessage(static fn() => v::not(v::equivalent(true))->assert(1)); -?> ---EXPECT-- -`false` must be equivalent to `true` -"someThing" must not be equivalent to "Something" -- "true" must be equivalent to 123 -- 1 must not be equivalent to `true` diff --git a/tests/integration/rules/even.phpt b/tests/integration/rules/even.phpt deleted file mode 100644 index 9d0d934ef..000000000 --- a/tests/integration/rules/even.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::even()->assert(-1)); -exceptionFullMessage(static fn() => v::even()->assert(5)); -exceptionMessage(static fn() => v::not(v::even())->assert(6)); -exceptionFullMessage(static fn() => v::not(v::even())->assert(8)); -?> ---EXPECT-- --1 must be an even number -- 5 must be an even number -6 must be an odd number -- 8 must be an odd number \ No newline at end of file diff --git a/tests/integration/rules/executable.phpt b/tests/integration/rules/executable.phpt deleted file mode 100644 index 377d480e5..000000000 --- a/tests/integration/rules/executable.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::executable()->assert('bar')); -exceptionMessage(static fn() => v::not(v::executable())->assert('tests/fixtures/executable')); -exceptionFullMessage(static fn() => v::executable()->assert('bar')); -exceptionFullMessage(static fn() => v::not(v::executable())->assert('tests/fixtures/executable')); -?> ---EXPECT-- -"bar" must be an executable file -"tests/fixtures/executable" must not be an executable file -- "bar" must be an executable file -- "tests/fixtures/executable" must not be an executable file diff --git a/tests/integration/rules/exists.phpt b/tests/integration/rules/exists.phpt deleted file mode 100644 index d7e44d1af..000000000 --- a/tests/integration/rules/exists.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::exists()->assert('/path/of/a/non-existent/file')); -exceptionMessage(static fn() => v::not(v::exists())->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::exists()->assert('/path/of/a/non-existent/file')); -exceptionFullMessage(static fn() => v::not(v::exists())->assert('tests/fixtures/valid-image.png')); -?> ---EXPECT-- -"/path/of/a/non-existent/file" must be an existing file -"tests/fixtures/valid-image.gif" must not be an existing file -- "/path/of/a/non-existent/file" must be an existing file -- "tests/fixtures/valid-image.png" must not be an existing file \ No newline at end of file diff --git a/tests/integration/rules/extension.phpt b/tests/integration/rules/extension.phpt deleted file mode 100644 index 8328d4c2c..000000000 --- a/tests/integration/rules/extension.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::extension('png')->assert('filename.txt')); -exceptionMessage(static fn() => v::not(v::extension('gif'))->assert('filename.gif')); -exceptionFullMessage(static fn() => v::extension('mp3')->assert('filename.wav')); -exceptionFullMessage(static fn() => v::not(v::extension('png'))->assert('tests/fixtures/invalid-image.png')); -?> ---EXPECT-- -"filename.txt" must have "png" extension -"filename.gif" must not have "gif" extension -- "filename.wav" must have "mp3" extension -- "tests/fixtures/invalid-image.png" must not have "png" extension diff --git a/tests/integration/rules/factor.phpt b/tests/integration/rules/factor.phpt deleted file mode 100644 index 36a0566b8..000000000 --- a/tests/integration/rules/factor.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::factor(3)->assert(2)); -exceptionMessage(static fn() => v::not(v::factor(0))->assert(300)); -exceptionFullMessage(static fn() => v::factor(5)->assert(3)); -exceptionFullMessage(static fn() => v::not(v::factor(6))->assert(1)); -?> ---EXPECT-- -2 must be a factor of 3 -300 must not be a factor of 0 -- 3 must be a factor of 5 -- 1 must not be a factor of 6 diff --git a/tests/integration/rules/falseVal.phpt b/tests/integration/rules/falseVal.phpt deleted file mode 100644 index 9126cc378..000000000 --- a/tests/integration/rules/falseVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::falseVal()->assert(true)); -exceptionMessage(static fn() => v::not(v::falseVal())->assert('false')); -exceptionFullMessage(static fn() => v::falseVal()->assert(1)); -exceptionFullMessage(static fn() => v::not(v::falseVal())->assert(0)); -?> ---EXPECT-- -`true` must evaluate to `false` -"false" must not evaluate to `false` -- 1 must evaluate to `false` -- 0 must not evaluate to `false` diff --git a/tests/integration/rules/fibonacci.phpt b/tests/integration/rules/fibonacci.phpt deleted file mode 100644 index 3ea7fb3ef..000000000 --- a/tests/integration/rules/fibonacci.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::fibonacci()->assert(4)); -exceptionMessage(static fn() => v::not(v::fibonacci())->assert(5)); -exceptionFullMessage(static fn() => v::fibonacci()->assert(16)); -exceptionFullMessage(static fn() => v::not(v::fibonacci())->assert(21)); -?> ---EXPECT-- -4 must be a valid Fibonacci number -5 must not be a valid Fibonacci number -- 16 must be a valid Fibonacci number -- 21 must not be a valid Fibonacci number diff --git a/tests/integration/rules/file.phpt b/tests/integration/rules/file.phpt deleted file mode 100644 index be8f013cc..000000000 --- a/tests/integration/rules/file.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::file()->assert('tests/fixtures/non-existent.sh')); -exceptionMessage(static fn() => v::not(v::file())->assert('tests/fixtures/valid-image.png')); -exceptionFullMessage(static fn() => v::file()->assert('tests/fixtures/non-existent.sh')); -exceptionFullMessage(static fn() => v::not(v::file())->assert('tests/fixtures/valid-image.png')); -?> ---EXPECT-- -"tests/fixtures/non-existent.sh" must be a valid file -"tests/fixtures/valid-image.png" must be an invalid file -- "tests/fixtures/non-existent.sh" must be a valid file -- "tests/fixtures/valid-image.png" must be an invalid file \ No newline at end of file diff --git a/tests/integration/rules/filterVar.phpt b/tests/integration/rules/filterVar.phpt deleted file mode 100644 index 45adebe37..000000000 --- a/tests/integration/rules/filterVar.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::filterVar(FILTER_VALIDATE_IP)->assert(42)); -exceptionMessage(static fn() => v::not(v::filterVar(FILTER_VALIDATE_BOOLEAN))->assert('On')); -exceptionFullMessage(static fn() => v::filterVar(FILTER_VALIDATE_EMAIL)->assert(1.5)); -exceptionFullMessage(static fn() => v::not(v::filterVar(FILTER_VALIDATE_FLOAT))->assert(1.0)); -?> ---EXPECT-- -42 must be valid -"On" must not be valid -- 1.5 must be valid -- 1.0 must not be valid diff --git a/tests/integration/rules/finite.phpt b/tests/integration/rules/finite.phpt deleted file mode 100644 index f893b9cc3..000000000 --- a/tests/integration/rules/finite.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::finite()->assert('')); -exceptionMessage(static fn() => v::not(v::finite())->assert(10)); -exceptionFullMessage(static fn() => v::finite()->assert([12])); -exceptionFullMessage(static fn() => v::not(v::finite())->assert('123456')); -?> ---EXPECT-- -"" must be a finite number -10 must not be a finite number -- `[12]` must be a finite number -- "123456" must not be a finite number diff --git a/tests/integration/rules/floatType.phpt b/tests/integration/rules/floatType.phpt deleted file mode 100644 index 87b7e132e..000000000 --- a/tests/integration/rules/floatType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::floatType()->assert('42.33')); -exceptionMessage(static fn() => v::not(v::floatType())->assert(INF)); -exceptionFullMessage(static fn() => v::floatType()->assert(true)); -exceptionFullMessage(static fn() => v::not(v::floatType())->assert(2.0)); -?> ---EXPECT-- -"42.33" must be float -`INF` must not be float -- `true` must be float -- 2.0 must not be float \ No newline at end of file diff --git a/tests/integration/rules/floatval.phpt b/tests/integration/rules/floatval.phpt deleted file mode 100644 index 7d676174a..000000000 --- a/tests/integration/rules/floatval.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::floatVal()->assert('a')); -exceptionMessage(static fn() => v::not(v::floatVal())->assert(165.0)); -exceptionFullMessage(static fn() => v::floatVal()->assert('a')); -exceptionFullMessage(static fn() => v::not(v::floatVal())->assert('165.7')); -?> ---EXPECT-- -"a" must be a float value -165.0 must not be a float value -- "a" must be a float value -- "165.7" must not be a float value \ No newline at end of file diff --git a/tests/integration/rules/graph.phpt b/tests/integration/rules/graph.phpt deleted file mode 100644 index 1bbb6a468..000000000 --- a/tests/integration/rules/graph.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::graph()->assert("foo\nbar")); -exceptionMessage(static fn() => v::graph('foo')->assert("foo\nbar")); -exceptionMessage(static fn() => v::not(v::graph())->assert('foobar')); -exceptionMessage(static fn() => v::not(v::graph("\n"))->assert("foo\nbar")); -exceptionFullMessage(static fn() => v::graph()->assert("foo\nbar")); -exceptionFullMessage(static fn() => v::graph('foo')->assert("foo\nbar")); -exceptionFullMessage(static fn() => v::not(v::graph())->assert('foobar')); -exceptionFullMessage(static fn() => v::not(v::graph("\n"))->assert("foo\nbar")); -?> ---EXPECT-- -"foo\nbar" must contain only graphical characters -"foo\nbar" must contain only graphical characters and "foo" -"foobar" must not contain graphical characters -"foo\nbar" must not contain graphical characters or "\n" -- "foo\nbar" must contain only graphical characters -- "foo\nbar" must contain only graphical characters and "foo" -- "foobar" must not contain graphical characters -- "foo\nbar" must not contain graphical characters or "\n" diff --git a/tests/integration/rules/greaterThan.phpt b/tests/integration/rules/greaterThan.phpt deleted file mode 100644 index feb1a5070..000000000 --- a/tests/integration/rules/greaterThan.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::greaterThan(21)->assert(12)); -exceptionMessage(static fn() => v::not(v::greaterThan('yesterday'))->assert('today')); -exceptionFullMessage(static fn() => v::greaterThan('2018-09-09')->assert('1988-09-09')); -exceptionFullMessage(static fn() => v::not(v::greaterThan('a'))->assert('ba')); -?> ---EXPECT-- -12 must be greater than 21 -"today" must not be greater than "yesterday" -- "1988-09-09" must be greater than "2018-09-09" -- "ba" must not be greater than "a" diff --git a/tests/integration/rules/greaterThanOrEqual.phpt b/tests/integration/rules/greaterThanOrEqual.phpt deleted file mode 100644 index 66c47f633..000000000 --- a/tests/integration/rules/greaterThanOrEqual.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::greaterThanOrEqual(INF)->assert(10)); -exceptionMessage(static fn() => v::not(v::greaterThanOrEqual(5))->assert(INF)); -exceptionFullMessage(static fn() => v::greaterThanOrEqual('today')->assert('yesterday')); -exceptionFullMessage(static fn() => v::not(v::greaterThanOrEqual('a'))->assert('z')); -?> ---EXPECT-- -10 must be greater than or equal to `INF` -`INF` must be less than 5 -- "yesterday" must be greater than or equal to "today" -- "z" must be less than "a" \ No newline at end of file diff --git a/tests/integration/rules/hetu.phpt b/tests/integration/rules/hetu.phpt deleted file mode 100644 index 82b97e882..000000000 --- a/tests/integration/rules/hetu.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---FILE-- - [v::hetu(), '010106A901O'], - 'Inverted' => [v::not(v::hetu()), '010106A9012'], - 'With template' => [v::hetu(), '010106A901O', 'That is not a HETU'], - 'With name' => [v::hetu()->setName('Hetu'), '010106A901O'], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -"010106A901O" must be a valid Finnish personal identity code -- "010106A901O" must be a valid Finnish personal identity code -[ - 'hetu' => '"010106A901O" must be a valid Finnish personal identity code', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -"010106A9012" must not be a valid Finnish personal identity code -- "010106A9012" must not be a valid Finnish personal identity code -[ - 'notHetu' => '"010106A9012" must not be a valid Finnish personal identity code', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -That is not a HETU -- That is not a HETU -[ - 'hetu' => 'That is not a HETU', -] - -With name -⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Hetu must be a valid Finnish personal identity code -- Hetu must be a valid Finnish personal identity code -[ - 'hetu' => 'Hetu must be a valid Finnish personal identity code', -] diff --git a/tests/integration/rules/hexRgbColor.phpt b/tests/integration/rules/hexRgbColor.phpt deleted file mode 100644 index 52095816c..000000000 --- a/tests/integration/rules/hexRgbColor.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::hexRgbColor()->assert('invalid')); -exceptionMessage(static fn() => v::not(v::hexRgbColor())->assert('#808080')); -exceptionFullMessage(static fn() => v::hexRgbColor()->assert('invalid')); -exceptionFullMessage(static fn() => v::not(v::hexRgbColor())->assert('#808080')); -?> ---EXPECT-- -"invalid" must be a hex RGB color -"#808080" must not be a hex RGB color -- "invalid" must be a hex RGB color -- "#808080" must not be a hex RGB color diff --git a/tests/integration/rules/iban.phpt b/tests/integration/rules/iban.phpt deleted file mode 100644 index abd33a03b..000000000 --- a/tests/integration/rules/iban.phpt +++ /dev/null @@ -1,20 +0,0 @@ ---FILE-- - v::iban()->assert('SE35 5000 5880 7742')); -exceptionMessage(static fn() => v::not(v::iban())->assert('GB82 WEST 1234 5698 7654 32')); -exceptionFullMessage(static fn() => v::iban()->assert('NOT AN IBAN')); -exceptionFullMessage(static fn() => v::not(v::iban())->assert('HU93 1160 0006 0000 0000 1234 5676'));?> ---SKIPIF-- - ---EXPECT-- -"SE35 5000 5880 7742" must be a valid IBAN -"GB82 WEST 1234 5698 7654 32" must not be a valid IBAN -- "NOT AN IBAN" must be a valid IBAN -- "HU93 1160 0006 0000 0000 1234 5676" must not be a valid IBAN diff --git a/tests/integration/rules/identical.phpt b/tests/integration/rules/identical.phpt deleted file mode 100644 index 96ce4a2c9..000000000 --- a/tests/integration/rules/identical.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::identical(123)->assert(321)); -exceptionMessage(static fn() => v::not(v::identical(321))->assert(321)); -exceptionFullMessage(static fn() => v::identical(123)->assert(321)); -exceptionFullMessage(static fn() => v::not(v::identical(321))->assert(321)); -?> ---EXPECT-- -321 must be identical to 123 -321 must not be identical to 321 -- 321 must be identical to 123 -- 321 must not be identical to 321 \ No newline at end of file diff --git a/tests/integration/rules/image.phpt b/tests/integration/rules/image.phpt deleted file mode 100644 index c2c501a6b..000000000 --- a/tests/integration/rules/image.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::image()->assert('tests/fixtures/invalid-image.png')); -exceptionMessage(static fn() => v::not(v::image())->assert('tests/fixtures/valid-image.png')); -exceptionFullMessage(static fn() => v::image()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::image())->assert('tests/fixtures/valid-image.gif')); -?> ---EXPECT-- -"tests/fixtures/invalid-image.png" must be a valid image file -"tests/fixtures/valid-image.png" must not be a valid image file -- `stdClass {}` must be a valid image file -- "tests/fixtures/valid-image.gif" must not be a valid image file \ No newline at end of file diff --git a/tests/integration/rules/imei.phpt b/tests/integration/rules/imei.phpt deleted file mode 100644 index b09d01273..000000000 --- a/tests/integration/rules/imei.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::imei()->assert('490154203237512')); -exceptionMessage(static fn() => v::not(v::imei())->assert('350077523237513')); -exceptionFullMessage(static fn() => v::imei()->assert(null)); -exceptionFullMessage(static fn() => v::not(v::imei())->assert('356938035643809')); -?> ---EXPECT-- -"490154203237512" must be a valid IMEI number -"350077523237513" must not be a valid IMEI number -- `null` must be a valid IMEI number -- "356938035643809" must not be a valid IMEI number \ No newline at end of file diff --git a/tests/integration/rules/in.phpt b/tests/integration/rules/in.phpt deleted file mode 100644 index 672ad14eb..000000000 --- a/tests/integration/rules/in.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::in([3, 2])->assert(1)); -exceptionMessage(static fn() => v::not(v::in('foobar'))->assert('foo')); -exceptionFullMessage(static fn() => v::in([2, '1', 3], true)->assert('2')); -exceptionFullMessage(static fn() => v::not(v::in([2, '1', 3], true))->assert('1')); -?> ---EXPECT-- -1 must be in `[3, 2]` -"foo" must not be in "foobar" -- "2" must be in `[2, "1", 3]` -- "1" must not be in `[2, "1", 3]` diff --git a/tests/integration/rules/infinite.phpt b/tests/integration/rules/infinite.phpt deleted file mode 100644 index 4d0be9115..000000000 --- a/tests/integration/rules/infinite.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::infinite()->assert(-9)); -exceptionMessage(static fn() => v::not(v::infinite())->assert(INF)); -exceptionFullMessage(static fn() => v::infinite()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::infinite())->assert(INF * -1)); -?> ---EXPECT-- --9 must be an infinite number -`INF` must not be an infinite number -- `stdClass {}` must be an infinite number -- `-INF` must not be an infinite number diff --git a/tests/integration/rules/instance.phpt b/tests/integration/rules/instance.phpt deleted file mode 100644 index 5fe6ae9f8..000000000 --- a/tests/integration/rules/instance.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::instance(DateTime::class)->assert('')); -exceptionMessage(static fn() => v::not(v::instance(Traversable::class))->assert(new ArrayObject())); -exceptionFullMessage(static fn() => v::instance(ArrayIterator::class)->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::instance(stdClass::class))->assert(new stdClass())); -?> ---EXPECT-- -"" must be an instance of `DateTime` -`ArrayObject { getArrayCopy() => [] }` must not be an instance of `Traversable` -- `stdClass {}` must be an instance of `ArrayIterator` -- `stdClass {}` must not be an instance of `stdClass` diff --git a/tests/integration/rules/intType.phpt b/tests/integration/rules/intType.phpt deleted file mode 100644 index 92833a92b..000000000 --- a/tests/integration/rules/intType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::intType()->assert(new stdClass())); -exceptionMessage(static fn() => v::not(v::intType())->assert(42)); -exceptionFullMessage(static fn() => v::intType()->assert(INF)); -exceptionFullMessage(static fn() => v::not(v::intType())->assert(1234567890)); -?> ---EXPECT-- -`stdClass {}` must be an integer -42 must not be an integer -- `INF` must be an integer -- 1234567890 must not be an integer \ No newline at end of file diff --git a/tests/integration/rules/intVal.phpt b/tests/integration/rules/intVal.phpt deleted file mode 100644 index 8081b2d3c..000000000 --- a/tests/integration/rules/intVal.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - v::intVal()->assert('42.33')); -exceptionMessage(static fn() => v::not(v::intVal())->assert(2)); -exceptionFullMessage(static fn() => v::intVal()->assert('Foo')); -exceptionFullMessage(static fn() => v::not(v::intVal())->assert(3)); -exceptionFullMessage(static fn() => v::not(v::intVal())->assert(-42)); -exceptionFullMessage(static fn() => v::not(v::intVal())->assert('-42')); -?> ---EXPECT-- -"42.33" must be an integer value -2 must not be an integer value -- "Foo" must be an integer value -- 3 must not be an integer value -- -42 must not be an integer value -- "-42" must not be an integer value \ No newline at end of file diff --git a/tests/integration/rules/ip.phpt b/tests/integration/rules/ip.phpt deleted file mode 100644 index 955735358..000000000 --- a/tests/integration/rules/ip.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---FILE-- - v::ip()->assert('257.0.0.1')); -exceptionMessage(static fn() => v::not(v::ip())->assert('127.0.0.1')); -exceptionMessage(static fn() => v::ip('127.0.1.*')->assert('127.0.0.1')); -exceptionMessage(static fn() => v::not(v::ip('127.0.1.*'))->assert('127.0.1.1')); -exceptionFullMessage(static fn() => v::ip()->assert('257.0.0.1')); -exceptionFullMessage(static fn() => v::not(v::ip())->assert('127.0.0.1')); -exceptionFullMessage(static fn() => v::ip('127.0.1.*')->assert('127.0.0.1')); -exceptionFullMessage(static fn() => v::not(v::ip('127.0.1.*'))->assert('127.0.1.1'));?> ---SKIPIF-- - ---EXPECT-- -"257.0.0.1" must be an IP address -"127.0.0.1" must not be an IP address -"127.0.0.1" must be an IP address in the 127.0.1.0-127.0.1.255 range -"127.0.1.1" must not be an IP address in the 127.0.1.0-127.0.1.255 range -- "257.0.0.1" must be an IP address -- "127.0.0.1" must not be an IP address -- "127.0.0.1" must be an IP address in the 127.0.1.0-127.0.1.255 range -- "127.0.1.1" must not be an IP address in the 127.0.1.0-127.0.1.255 range diff --git a/tests/integration/rules/isbn.phpt b/tests/integration/rules/isbn.phpt deleted file mode 100644 index b01e8ad31..000000000 --- a/tests/integration/rules/isbn.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::isbn()->assert('ISBN-12: 978-0-596-52068-7')); -exceptionMessage(static fn() => v::not(v::isbn())->assert('ISBN-13: 978-0-596-52068-7')); -exceptionFullMessage(static fn() => v::isbn()->assert('978 10 596 52068 7')); -exceptionFullMessage(static fn() => v::not(v::isbn())->assert('978 0 596 52068 7')); -?> ---EXPECT-- -"ISBN-12: 978-0-596-52068-7" must be a valid ISBN -"ISBN-13: 978-0-596-52068-7" must not be a valid ISBN -- "978 10 596 52068 7" must be a valid ISBN -- "978 0 596 52068 7" must not be a valid ISBN \ No newline at end of file diff --git a/tests/integration/rules/iterableType.phpt b/tests/integration/rules/iterableType.phpt deleted file mode 100644 index 507132134..000000000 --- a/tests/integration/rules/iterableType.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---FILE-- - [v::iterableType(), null], - 'Inverted' => [v::not(v::iterableType()), [1, 2, 3]], - 'With template' => [v::iterableType(), null, 'Not an iterable at all'], - 'With name' => [v::iterableType()->setName('Options'), null], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -`null` must be iterable -- `null` must be iterable -[ - 'iterableType' => '`null` must be iterable', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -`[1, 2, 3]` must not iterable -- `[1, 2, 3]` must not iterable -[ - 'notIterableType' => '`[1, 2, 3]` must not iterable', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not an iterable at all -- Not an iterable at all -[ - 'iterableType' => 'Not an iterable at all', -] - -With name -⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Options must be iterable -- Options must be iterable -[ - 'iterableType' => 'Options must be iterable', -] diff --git a/tests/integration/rules/iterableVal.phpt b/tests/integration/rules/iterableVal.phpt deleted file mode 100644 index 925679116..000000000 --- a/tests/integration/rules/iterableVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::iterableVal()->assert(3)); -exceptionMessage(static fn() => v::not(v::iterableVal())->assert([2, 3])); -exceptionFullMessage(static fn() => v::iterableVal()->assert('String')); -exceptionFullMessage(static fn() => v::not(v::iterableVal())->assert(new stdClass())); -?> ---EXPECT-- -3 must be an iterable value -`[2, 3]` must not be an iterable value -- "String" must be an iterable value -- `stdClass {}` must not be an iterable value \ No newline at end of file diff --git a/tests/integration/rules/json.phpt b/tests/integration/rules/json.phpt deleted file mode 100644 index 8b4887d84..000000000 --- a/tests/integration/rules/json.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::json()->assert(false)); -exceptionMessage(static fn() => v::not(v::json())->assert('{"foo": "bar", "number":1}')); -exceptionFullMessage(static fn() => v::json()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::json())->assert('{}')); -?> ---EXPECT-- -`false` must be a valid JSON string -"{\"foo\": \"bar\", \"number\":1}" must not be a valid JSON string -- `stdClass {}` must be a valid JSON string -- "{}" must not be a valid JSON string diff --git a/tests/integration/rules/key.phpt b/tests/integration/rules/key.phpt deleted file mode 100644 index 76f08bdc6..000000000 --- a/tests/integration/rules/key.phpt +++ /dev/null @@ -1,154 +0,0 @@ ---FILE-- - [v::key('foo', v::intType()), []], - 'Default' => [v::key('foo', v::intType()), ['foo' => 'string']], - 'Inverted' => [v::not(v::key('foo', v::intType())), ['foo' => 12]], - 'Double-inverted with missing key' => [ - v::not(v::not(v::key('foo', v::intType()))), - [], - ], - - // With custom name - 'With wrapped name, missing key' => [ - v::key('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'), - [], - ], - 'With wrapped name, default' => [ - v::key('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'), - ['foo' => 'string'], - ], - 'With wrapped name, inverted' => [ - v::not(v::key('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not'), - ['foo' => 12], - ], - 'With wrapper name, default' => [ - v::key('foo', v::intType())->setName('Wrapper'), - ['foo' => 'string'], - ], - 'With wrapper name, missing key' => [ - v::key('foo', v::intType())->setName('Wrapper'), - [], - ], - 'With wrapper name, inverted' => [ - v::not(v::key('foo', v::intType())->setName('Wrapper'))->setName('Not'), - ['foo' => 12], - ], - 'With "Not" name, inverted' => [ - v::not(v::key('foo', v::intType()))->setName('Not'), - ['foo' => 12], - ], - - // With custom template - 'With template, default' => [v::key('foo', v::intType()), ['foo' => 'string'], 'That key is off-key'], - 'With template, inverted' => [v::not(v::key('foo', v::intType())), ['foo' => 12], 'No off-key key'], -]); -?> ---EXPECT-- -Missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -Default -⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -Double-inverted with missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -With wrapped name, missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be present -- Wrapped must be present -[ - 'foo' => 'Wrapped must be present', -] - -With wrapped name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be an integer -- Wrapped must be an integer -[ - 'foo' => 'Wrapped must be an integer', -] - -With wrapped name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be an integer -- Wrapped must not be an integer -[ - 'foo' => 'Wrapped must not be an integer', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -With wrapper name, missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With "Not" name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -That key is off-key -- That key is off-key -[ - 'foo' => 'That key is off-key', -] - -With template, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -No off-key key -- No off-key key -[ - 'foo' => 'No off-key key', -] diff --git a/tests/integration/rules/keyExists.phpt b/tests/integration/rules/keyExists.phpt deleted file mode 100644 index 638504115..000000000 --- a/tests/integration/rules/keyExists.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---FILE-- - [v::keyExists('foo'), ['bar' => 'baz']], - 'Inverted mode' => [v::not(v::keyExists('foo')), ['foo' => 'baz']], - 'Custom name' => [v::keyExists('foo')->setName('Custom name'), ['bar' => 'baz']], - 'Custom template' => [v::keyExists('foo'), ['bar' => 'baz'], 'Custom template for `{{name}}`'], -]); -?> ---EXPECT-- -Default mode -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -Inverted mode -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be present -- foo must not be present -[ - 'foo' => 'foo must not be present', -] - -Custom name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Custom name must be present -- Custom name must be present -[ - 'foo' => 'Custom name must be present', -] - -Custom template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Custom template for `foo` -- Custom template for `foo` -[ - 'foo' => 'Custom template for `foo`', -] diff --git a/tests/integration/rules/keyOptional.phpt b/tests/integration/rules/keyOptional.phpt deleted file mode 100644 index 4ce4753ac..000000000 --- a/tests/integration/rules/keyOptional.phpt +++ /dev/null @@ -1,121 +0,0 @@ ---FILE-- - [v::keyOptional('foo', v::intType()), ['foo' => 'string']], - 'Inverted' => [v::not(v::keyOptional('foo', v::intType())), ['foo' => 12]], - 'Inverted with missing key' => [ - v::not(v::keyOptional('foo', v::intType())), - [], - ], - - // With custom name - 'With wrapped name, default' => [ - v::keyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'), - ['foo' => 'string'], - ], - 'With wrapped name, inverted' => [ - v::not(v::keyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not'), - ['foo' => 12], - ], - 'With wrapper name, default' => [ - v::keyOptional('foo', v::intType())->setName('Wrapper'), - ['foo' => 'string'], - ], - 'With wrapper name, inverted' => [ - v::not(v::keyOptional('foo', v::intType())->setName('Wrapper'))->setName('Not'), - ['foo' => 12], - ], - 'With "Not" name, inverted' => [ - v::not(v::keyOptional('foo', v::intType()))->setName('Not'), - ['foo' => 12], - ], - - // With custom template - 'With template, default' => [v::keyOptional('foo', v::intType()), ['foo' => 'string'], 'That key is off-key'], - 'With template, inverted' => [v::not(v::keyOptional('foo', v::intType())), ['foo' => 12], 'No off-key key'], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -Inverted with missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -With wrapped name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be an integer -- Wrapped must be an integer -[ - 'foo' => 'Wrapped must be an integer', -] - -With wrapped name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be an integer -- Wrapped must not be an integer -[ - 'foo' => 'Wrapped must not be an integer', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With "Not" name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -That key is off-key -- That key is off-key -[ - 'foo' => 'That key is off-key', -] - -With template, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -No off-key key -- No off-key key -[ - 'foo' => 'No off-key key', -] diff --git a/tests/integration/rules/keySet.phpt b/tests/integration/rules/keySet.phpt deleted file mode 100644 index 7f273eccb..000000000 --- a/tests/integration/rules/keySet.phpt +++ /dev/null @@ -1,227 +0,0 @@ ---FILE-- - [v::keySet(v::key('foo', v::intType())), ['foo' => 'string']], - 'one rule / one missing key' => [v::keySet(v::keyExists('foo')), []], - 'one rule / one extra key' => [v::keySet(v::keyExists('foo')), ['foo' => 42, 'bar' => 'string']], - 'one rule / one extra key / one missing key' => [v::keySet(v::keyExists('foo')), ['bar' => true]], - 'one rule / two extra keys' => [v::keySet(v::keyExists('foo')), ['foo' => 42, 'bar' => 'string', 'baz' => true]], - 'one rule / more than ten extra keys' => [ - v::keySet(v::keyExists('foo')), - [ - 'foo' => 42, - 'bar' => 'string', - 'baz' => true, - 'qux' => false, - 'quux' => 42, - 'corge' => 'string', - 'grault' => true, - 'garply' => false, - 'waldo' => 42, - 'fred' => 'string', - 'plugh' => true, - 'xyzzy' => false, - 'thud' => 42, - ], - ], - 'multiple rules / one failed' => [ - v::keySet(v::keyExists('foo'), v::keyExists('bar')), - ['foo' => 42], - ], - 'multiple rules / all failed' => [ - v::keySet(v::keyExists('foo'), v::keyExists('bar')), - [], - ], - 'multiple rules / one extra key' => [ - v::keySet(v::keyExists('foo'), v::keyExists('bar')), - ['foo' => 42, 'bar' => 'string', 'baz' => true], - ], - 'multiple rules / one extra key / one missing' => [ - v::keySet( - v::keyExists('foo'), - v::keyExists('bar') - ), - ['bar' => 'string', 'baz' => true], - ], - 'multiple rules / two extra keys' => [ - v::keySet( - v::keyExists('foo'), - v::keyExists('bar'), - v::keyOptional('qux', v::intType()) - ), - ['foo' => 42, 'bar' => 'string', 'baz' => true, 'qux' => false], - ], - 'multiple rules / all failed validation' => [ - v::keySet( - v::key('foo', v::intType()), - v::key('bar', v::intType()), - v::key('baz', v::intType()) - ), - ['foo' => 42, 'bar' => 'string', 'baz' => true], - ], - 'multiple rules / single missing key / single failed validation' => [ - v::keySet( - v::create() - ->key('foo', v::intType()) - ->key('bar', v::intType()) - ->key('baz', v::intType()) - ), - ['foo' => 42, 'bar' => 'string'], - ], -]); -?> ---EXPECT-- -one rule / one failed -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -one rule / one missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -one rule / one extra key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -bar must not be present -- bar must not be present -[ - 'bar' => 'bar must not be present', -] - -one rule / one extra key / one missing key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- `["bar": true]` contains both missing and extra keys - - foo must be present - - bar must not be present -[ - '__root__' => '`["bar": true]` contains both missing and extra keys', - 'foo' => 'foo must be present', - 'bar' => 'bar must not be present', -] - -one rule / two extra keys -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -bar must not be present -- `["foo": 42, "bar": "string", "baz": true]` contains extra keys - - bar must not be present - - baz must not be present -[ - '__root__' => '`["foo": 42, "bar": "string", "baz": true]` contains extra keys', - 'bar' => 'bar must not be present', - 'baz' => 'baz must not be present', -] - -one rule / more than ten extra keys -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -bar must not be present -- `["foo": 42, "bar": "string", "baz": true, "qux": false, "quux": 42, ...]` contains extra keys - - bar must not be present - - baz must not be present - - qux must not be present - - quux must not be present - - corge must not be present - - grault must not be present - - garply must not be present - - waldo must not be present - - fred must not be present - - plugh must not be present -[ - '__root__' => '`["foo": 42, "bar": "string", "baz": true, "qux": false, "quux": 42, ...]` contains extra keys', - 'bar' => 'bar must not be present', - 'baz' => 'baz must not be present', - 'qux' => 'qux must not be present', - 'quux' => 'quux must not be present', - 'corge' => 'corge must not be present', - 'grault' => 'grault must not be present', - 'garply' => 'garply must not be present', - 'waldo' => 'waldo must not be present', - 'fred' => 'fred must not be present', - 'plugh' => 'plugh must not be present', -] - -multiple rules / one failed -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -bar must be present -- bar must be present -[ - 'bar' => 'bar must be present', -] - -multiple rules / all failed -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- `[]` contains missing keys - - foo must be present - - bar must be present -[ - '__root__' => '`[]` contains missing keys', - 'foo' => 'foo must be present', - 'bar' => 'bar must be present', -] - -multiple rules / one extra key -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -baz must not be present -- baz must not be present -[ - 'baz' => 'baz must not be present', -] - -multiple rules / one extra key / one missing -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- `["bar": "string", "baz": true]` contains both missing and extra keys - - foo must be present - - baz must not be present -[ - '__root__' => '`["bar": "string", "baz": true]` contains both missing and extra keys', - 'foo' => 'foo must be present', - 'baz' => 'baz must not be present', -] - -multiple rules / two extra keys -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -qux must be an integer -- `["foo": 42, "bar": "string", "baz": true, "qux": false]` contains extra keys - - qux must be an integer - - baz must not be present -[ - '__root__' => '`["foo": 42, "bar": "string", "baz": true, "qux": false]` contains extra keys', - 'qux' => 'qux must be an integer', - 'baz' => 'baz must not be present', -] - -multiple rules / all failed validation -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -bar must be an integer -- `["foo": 42, "bar": "string", "baz": true]` validation failed - - bar must be an integer - - baz must be an integer -[ - '__root__' => '`["foo": 42, "bar": "string", "baz": true]` validation failed', - 'bar' => 'bar must be an integer', - 'baz' => 'baz must be an integer', -] - -multiple rules / single missing key / single failed validation -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -bar must be an integer -- `["foo": 42, "bar": "string"]` contains missing keys - - bar must be an integer - - baz must be present -[ - '__root__' => '`["foo": 42, "bar": "string"]` contains missing keys', - 'bar' => 'bar must be an integer', - 'baz' => 'baz must be present', -] diff --git a/tests/integration/rules/languageCode.phpt b/tests/integration/rules/languageCode.phpt deleted file mode 100644 index d5fd44211..000000000 --- a/tests/integration/rules/languageCode.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::languageCode()->assert(null)); -exceptionMessage(static fn() => v::not(v::languageCode())->assert('pt')); -exceptionFullMessage(static fn() => v::languageCode()->assert('por')); -exceptionFullMessage(static fn() => v::not(v::languageCode())->assert('en')); -?> ---EXPECT-- -`null` must be a valid language code -"pt" must not be a valid language code -- "por" must be a valid language code -- "en" must not be a valid language code diff --git a/tests/integration/rules/lazy.phpt b/tests/integration/rules/lazy.phpt deleted file mode 100644 index 4f8d580da..000000000 --- a/tests/integration/rules/lazy.phpt +++ /dev/null @@ -1,99 +0,0 @@ ---FILE-- - [v::lazy(static fn() => v::intType()), true], - 'Inverted' => [v::not(v::lazy(static fn() => v::intType())), 2], - 'With created name, default' => [ - v::lazy(static fn() => v::intType()->setName('Created'))->setName('Wrapper'), - true, - ], - 'With wrapper name, default' => [ - v::lazy(static fn() => v::intType())->setName('Wrapper'), - true, - ], - 'With created name, inverted' => [ - v::not(v::lazy(static fn() => v::intType()->setName('Created'))->setName('Wrapped'))->setName('Not'), - 2, - ], - 'With wrapper name, inverted' => [ - v::not(v::lazy(static fn() => v::intType())->setName('Wrapped'))->setName('Not'), - 2, - ], - 'With not name, inverted' => [ - v::not(v::lazy(static fn() => v::intType()))->setName('Not'), - 2, - ], - 'With template, default' => [ - v::lazy(static fn() => v::intType()), - true, - 'Lazy lizards lounging like lords in the local lagoon', - ], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -`true` must be an integer -- `true` must be an integer -[ - 'intType' => '`true` must be an integer', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -2 must not be an integer -- 2 must not be an integer -[ - 'notIntType' => '2 must not be an integer', -] - -With created name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Created must be an integer -- Created must be an integer -[ - 'intType' => 'Created must be an integer', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must be an integer -- Wrapper must be an integer -[ - 'intType' => 'Wrapper must be an integer', -] - -With created name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Created must not be an integer -- Created must not be an integer -[ - 'notIntType' => 'Created must not be an integer', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be an integer -- Wrapped must not be an integer -[ - 'notIntType' => 'Wrapped must not be an integer', -] - -With not name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not must not be an integer -- Not must not be an integer -[ - 'notIntType' => 'Not must not be an integer', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Lazy lizards lounging like lords in the local lagoon -- Lazy lizards lounging like lords in the local lagoon -[ - 'intType' => 'Lazy lizards lounging like lords in the local lagoon', -] diff --git a/tests/integration/rules/leapDate.phpt b/tests/integration/rules/leapDate.phpt deleted file mode 100644 index 40964c745..000000000 --- a/tests/integration/rules/leapDate.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::leapDate('Y-m-d')->assert('1989-02-29')); -exceptionMessage(static fn() => v::not(v::leapDate('Y-m-d'))->assert('1988-02-29')); -exceptionFullMessage(static fn() => v::leapDate('Y-m-d')->assert('1990-02-29')); -exceptionFullMessage(static fn() => v::not(v::leapDate('Y-m-d'))->assert('1992-02-29')); -?> ---EXPECT-- -"1989-02-29" must be a valid leap date -"1988-02-29" must not be a leap date -- "1990-02-29" must be a valid leap date -- "1992-02-29" must not be a leap date \ No newline at end of file diff --git a/tests/integration/rules/leapYear.phpt b/tests/integration/rules/leapYear.phpt deleted file mode 100644 index c50e39cdc..000000000 --- a/tests/integration/rules/leapYear.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::leapYear()->assert('2009')); -exceptionMessage(static fn() => v::not(v::leapYear())->assert('2008')); -exceptionFullMessage(static fn() => v::leapYear()->assert('2009-02-29')); -exceptionFullMessage(static fn() => v::not(v::leapYear())->assert('2008')); -?> ---EXPECT-- -"2009" must be a valid leap year -"2008" must not be a leap year -- "2009-02-29" must be a valid leap year -- "2008" must not be a leap year \ No newline at end of file diff --git a/tests/integration/rules/length.phpt b/tests/integration/rules/length.phpt deleted file mode 100644 index 4dd621300..000000000 --- a/tests/integration/rules/length.phpt +++ /dev/null @@ -1,53 +0,0 @@ ---FILE-- - [v::length(v::equals(3)), 'tulip'], - 'Inverted wrapped' => [v::length(v::not(v::equals(4))), 'rose'], - 'Inverted wrapper' => [v::not(v::length(v::equals(4))), 'fern'], - 'With template' => [v::length(v::equals(3)), 'azalea', 'This is a template'], - 'With wrapper name' => [v::length(v::equals(3))->setName('Cactus'), 'peyote'], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -The length of "tulip" must be equal to 3 -- The length of "tulip" must be equal to 3 -[ - 'lengthEquals' => 'The length of "tulip" must be equal to 3', -] - -Inverted wrapped -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The length of "rose" must not be equal to 4 -- The length of "rose" must not be equal to 4 -[ - 'lengthNotEquals' => 'The length of "rose" must not be equal to 4', -] - -Inverted wrapper -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The length of "fern" must not be equal to 4 -- The length of "fern" must not be equal to 4 -[ - 'notLengthEquals' => 'The length of "fern" must not be equal to 4', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -This is a template -- This is a template -[ - 'lengthEquals' => 'This is a template', -] - -With wrapper name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The length of Cactus must be equal to 3 -- The length of Cactus must be equal to 3 -[ - 'lengthEquals' => 'The length of Cactus must be equal to 3', -] diff --git a/tests/integration/rules/lessThan.phpt b/tests/integration/rules/lessThan.phpt deleted file mode 100644 index 251fbc423..000000000 --- a/tests/integration/rules/lessThan.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::lessThan(12)->assert(21)); -exceptionMessage(static fn() => v::not(v::lessThan('today'))->assert('yesterday')); -exceptionFullMessage(static fn() => v::lessThan('1988-09-09')->assert('2018-09-09')); -exceptionFullMessage(static fn() => v::not(v::lessThan('b'))->assert('a')); -?> ---EXPECT-- -21 must be less than 12 -"yesterday" must not be less than "today" -- "2018-09-09" must be less than "1988-09-09" -- "a" must not be less than "b" diff --git a/tests/integration/rules/lessThanOrEqual.phpt b/tests/integration/rules/lessThanOrEqual.phpt deleted file mode 100644 index 487437c3b..000000000 --- a/tests/integration/rules/lessThanOrEqual.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::lessThanOrEqual(10)->assert(11)); -exceptionMessage(static fn() => v::not(v::lessThanOrEqual(10))->assert(5)); -exceptionFullMessage(static fn() => v::lessThanOrEqual('today')->assert('tomorrow')); -exceptionFullMessage(static fn() => v::not(v::lessThanOrEqual('b'))->assert('a')); -?> ---EXPECT-- -11 must be less than or equal to 10 -5 must be greater than 10 -- "tomorrow" must be less than or equal to "today" -- "a" must be greater than "b" \ No newline at end of file diff --git a/tests/integration/rules/lowercase.phpt b/tests/integration/rules/lowercase.phpt deleted file mode 100644 index c98ed3523..000000000 --- a/tests/integration/rules/lowercase.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::lowercase()->assert('UPPERCASE')); -exceptionMessage(static fn() => v::not(v::lowercase())->assert('lowercase')); -exceptionFullMessage(static fn() => v::lowercase()->assert('UPPERCASE')); -exceptionFullMessage(static fn() => v::not(v::lowercase())->assert('lowercase')); -?> ---EXPECT-- -"UPPERCASE" must contain only lowercase letters -"lowercase" must not contain only lowercase letters -- "UPPERCASE" must contain only lowercase letters -- "lowercase" must not contain only lowercase letters \ No newline at end of file diff --git a/tests/integration/rules/luhn.phpt b/tests/integration/rules/luhn.phpt deleted file mode 100644 index 785267c60..000000000 --- a/tests/integration/rules/luhn.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::luhn()->assert('2222400041240021')); -exceptionMessage(static fn() => v::not(v::luhn())->assert('2223000048400011')); -exceptionFullMessage(static fn() => v::luhn()->assert('340316193809334')); -exceptionFullMessage(static fn() => v::not(v::luhn())->assert('6011000990139424')); -?> ---EXPECT-- -"2222400041240021" must be a valid Luhn number -"2223000048400011" must not be a valid Luhn number -- "340316193809334" must be a valid Luhn number -- "6011000990139424" must not be a valid Luhn number diff --git a/tests/integration/rules/macAddress.phpt b/tests/integration/rules/macAddress.phpt deleted file mode 100644 index 40588b0f9..000000000 --- a/tests/integration/rules/macAddress.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::macAddress()->assert('00-11222:33:44:55')); -exceptionMessage(static fn() => v::not(v::macAddress())->assert('00:11:22:33:44:55')); -exceptionFullMessage(static fn() => v::macAddress()->assert('90-bc-nk:1a-dd-cc')); -exceptionFullMessage(static fn() => v::not(v::macAddress())->assert('AF:0F:bd:12:44:ba')); -?> ---EXPECT-- -"00-11222:33:44:55" must be a valid MAC address -"00:11:22:33:44:55" must not be a valid MAC address -- "90-bc-nk:1a-dd-cc" must be a valid MAC address -- "AF:0F:bd:12:44:ba" must not be a valid MAC address diff --git a/tests/integration/rules/max.phpt b/tests/integration/rules/max.phpt deleted file mode 100644 index 2c89e7df8..000000000 --- a/tests/integration/rules/max.phpt +++ /dev/null @@ -1,96 +0,0 @@ ---FILE-- - [v::max(v::negative()), $nonIterable], - 'Empty' => [v::max(v::negative()), $empty], - 'Default' => [v::max(v::negative()), $default], - 'Inverted' => [v::not(v::max(v::negative())), $negative], - 'With wrapped name, default' => [v::max(v::negative()->setName('Wrapped'))->setName('Wrapper'), $default], - 'With wrapper name, default' => [v::max(v::negative())->setName('Wrapper'), $default], - 'With wrapped name, inverted' => [v::not(v::max(v::negative()->setName('Wrapped')))->setName('Wrapper'), $negative], - 'With wrapper name, inverted' => [v::not(v::max(v::negative()))->setName('Wrapper'), $negative], - 'With template, default' => [v::max(v::negative()), $default, 'The maximum of the value is not what we expect'], -]); -?> ---EXPECT-- -Non-iterable -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -`null` must be iterable -- `null` must be iterable -[ - 'max' => '`null` must be iterable', -] - -Empty -⎺⎺⎺⎺⎺ -The value must not be empty -- The value must not be empty -[ - 'max' => 'The value must not be empty', -] - -Default -⎺⎺⎺⎺⎺⎺⎺ -As the maximum of `[1, 2, 3]`, 3 must be a negative number -- As the maximum of `[1, 2, 3]`, 3 must be a negative number -[ - 'maxNegative' => 'As the maximum of `[1, 2, 3]`, 3 must be a negative number', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -As the maximum of `[-3, -2, -1]`, -1 must not be a negative number -- As the maximum of `[-3, -2, -1]`, -1 must not be a negative number -[ - 'notMaxNegative' => 'As the maximum of `[-3, -2, -1]`, -1 must not be a negative number', -] - -With wrapped name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The maximum of Wrapped must be a negative number -- The maximum of Wrapped must be a negative number -[ - 'maxNegative' => 'The maximum of Wrapped must be a negative number', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The maximum of Wrapper must be a negative number -- The maximum of Wrapper must be a negative number -[ - 'maxNegative' => 'The maximum of Wrapper must be a negative number', -] - -With wrapped name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The maximum of Wrapped must not be a negative number -- The maximum of Wrapped must not be a negative number -[ - 'notMaxNegative' => 'The maximum of Wrapped must not be a negative number', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The maximum of Wrapper must not be a negative number -- The maximum of Wrapper must not be a negative number -[ - 'notMaxNegative' => 'The maximum of Wrapper must not be a negative number', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The maximum of the value is not what we expect -- The maximum of the value is not what we expect -[ - 'maxNegative' => 'The maximum of the value is not what we expect', -] diff --git a/tests/integration/rules/mimetype.phpt b/tests/integration/rules/mimetype.phpt deleted file mode 100644 index 5ff1c636e..000000000 --- a/tests/integration/rules/mimetype.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::mimetype('image/png')->assert('image.png')); -exceptionMessage(static fn() => v::not(v::mimetype('image/png'))->assert('tests/fixtures/valid-image.png')); -exceptionFullMessage(static fn() => v::mimetype('image/png')->assert('tests/fixtures/invalid-image.png')); -exceptionFullMessage(static fn() => v::not(v::mimetype('image/png'))->assert('tests/fixtures/valid-image.png')); -?> ---EXPECT-- -"image.png" must have the "image/png" MIME type -"tests/fixtures/valid-image.png" must not have the "image/png" MIME type -- "tests/fixtures/invalid-image.png" must have the "image/png" MIME type -- "tests/fixtures/valid-image.png" must not have the "image/png" MIME type \ No newline at end of file diff --git a/tests/integration/rules/min.phpt b/tests/integration/rules/min.phpt deleted file mode 100644 index 36ba95c15..000000000 --- a/tests/integration/rules/min.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---FILE-- - [v::min(v::equals(1)), [2, 3]], - 'Inverted' => [v::not(v::min(v::equals(1))), [1, 2, 3]], - 'With template' => [v::min(v::equals(1)), [2, 3], 'That did not go as planned'], - 'With name' => [v::min(v::equals(1))->setName('Options'), [2, 3]], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -As the minimum from `[2, 3]`, 2 must be equal to 1 -- As the minimum from `[2, 3]`, 2 must be equal to 1 -[ - 'minEquals' => 'As the minimum from `[2, 3]`, 2 must be equal to 1', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -As the minimum from `[1, 2, 3]`, 1 must not be equal to 1 -- As the minimum from `[1, 2, 3]`, 1 must not be equal to 1 -[ - 'notMinEquals' => 'As the minimum from `[1, 2, 3]`, 1 must not be equal to 1', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -That did not go as planned -- That did not go as planned -[ - 'minEquals' => 'That did not go as planned', -] - -With name -⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The minimum from Options must be equal to 1 -- The minimum from Options must be equal to 1 -[ - 'minEquals' => 'The minimum from Options must be equal to 1', -] diff --git a/tests/integration/rules/multiple.phpt b/tests/integration/rules/multiple.phpt deleted file mode 100644 index d15f4992d..000000000 --- a/tests/integration/rules/multiple.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::multiple(3)->assert(22)); -exceptionMessage(static fn() => v::not(v::multiple(3))->assert(9)); -exceptionFullMessage(static fn() => v::multiple(2)->assert(5)); -exceptionFullMessage(static fn() => v::not(v::multiple(5))->assert(25)); -?> ---EXPECT-- -22 must be a multiple of 3 -9 must not be a multiple of 3 -- 5 must be a multiple of 2 -- 25 must not be a multiple of 5 \ No newline at end of file diff --git a/tests/integration/rules/negative.phpt b/tests/integration/rules/negative.phpt deleted file mode 100644 index 019585df7..000000000 --- a/tests/integration/rules/negative.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::negative()->assert(16)); -exceptionMessage(static fn() => v::not(v::negative())->assert(-10)); -exceptionFullMessage(static fn() => v::negative()->assert('a')); -exceptionFullMessage(static fn() => v::not(v::negative())->assert('-144')); -?> ---EXPECT-- -16 must be a negative number --10 must not be a negative number -- "a" must be a negative number -- "-144" must not be a negative number \ No newline at end of file diff --git a/tests/integration/rules/nfeAccessKey.phpt b/tests/integration/rules/nfeAccessKey.phpt deleted file mode 100644 index ffeaf7010..000000000 --- a/tests/integration/rules/nfeAccessKey.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::nfeAccessKey()->assert('31841136830118868211870485416765268625116906')); -exceptionMessage(static fn() => v::not(v::nfeAccessKey())->assert('52060433009911002506550120000007800267301615')); -exceptionFullMessage(static fn() => v::nfeAccessKey()->assert('31841136830118868211870485416765268625116906')); -exceptionFullMessage(static fn() => v::not(v::nfeAccessKey())->assert('52060433009911002506550120000007800267301615')); -?> ---EXPECT-- -"31841136830118868211870485416765268625116906" must be a valid NFe access key -"52060433009911002506550120000007800267301615" must not be a valid NFe access key -- "31841136830118868211870485416765268625116906" must be a valid NFe access key -- "52060433009911002506550120000007800267301615" must not be a valid NFe access key diff --git a/tests/integration/rules/nif.phpt b/tests/integration/rules/nif.phpt deleted file mode 100644 index c37580f70..000000000 --- a/tests/integration/rules/nif.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::nif()->assert('06357771Q')); -exceptionMessage(static fn() => v::not(v::nif())->assert('71110316C')); -exceptionFullMessage(static fn() => v::nif()->assert('06357771Q')); -exceptionFullMessage(static fn() => v::not(v::nif())->assert('R1332622H')); -?> ---EXPECT-- -"06357771Q" must be a valid NIF -"71110316C" must not be a valid NIF -- "06357771Q" must be a valid NIF -- "R1332622H" must not be a valid NIF \ No newline at end of file diff --git a/tests/integration/rules/nip.phpt b/tests/integration/rules/nip.phpt deleted file mode 100644 index 6d04f2e45..000000000 --- a/tests/integration/rules/nip.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::nip()->assert('1645865778')); -exceptionMessage(static fn() => v::not(v::nip())->assert('1645865777')); -exceptionFullMessage(static fn() => v::nip()->assert('1645865778')); -exceptionFullMessage(static fn() => v::not(v::nip())->assert('1645865777')); -?> ---EXPECT-- -"1645865778" must be a valid Polish VAT identification number -"1645865777" must not be a valid Polish VAT identification number -- "1645865778" must be a valid Polish VAT identification number -- "1645865777" must not be a valid Polish VAT identification number diff --git a/tests/integration/rules/no.phpt b/tests/integration/rules/no.phpt deleted file mode 100644 index a92f67936..000000000 --- a/tests/integration/rules/no.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::not(v::no())->assert('No')); -exceptionMessage(static fn() => v::no()->assert('Yes')); -exceptionFullMessage(static fn() => v::not(v::no())->assert('No')); -exceptionFullMessage(static fn() => v::no()->assert('Yes')); -?> ---EXPECT-- -"No" must not be similar to "No" -"Yes" must be similar to "No" -- "No" must not be similar to "No" -- "Yes" must be similar to "No" diff --git a/tests/integration/rules/noWhitespace.phpt b/tests/integration/rules/noWhitespace.phpt deleted file mode 100644 index 9befb89ba..000000000 --- a/tests/integration/rules/noWhitespace.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::noWhitespace()->assert('w poiur')); -exceptionMessage(static fn() => v::not(v::noWhitespace())->assert('wpoiur')); -exceptionFullMessage(static fn() => v::noWhitespace()->assert('w poiur')); -exceptionFullMessage(static fn() => v::not(v::noWhitespace())->assert('wpoiur')); -?> ---EXPECT-- -"w poiur" must not contain whitespaces -"wpoiur" must contain at least one whitespace -- "w poiur" must not contain whitespaces -- "wpoiur" must contain at least one whitespace \ No newline at end of file diff --git a/tests/integration/rules/noneOf.phpt b/tests/integration/rules/noneOf.phpt deleted file mode 100644 index 065fcc7af..000000000 --- a/tests/integration/rules/noneOf.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - v::noneOf(v::intType(), v::positive())->assert(42)); -exceptionMessage(static fn() => v::not(v::noneOf(v::intType(), v::positive()))->assert('-1')); -exceptionFullMessage(static fn() => v::noneOf(v::intType(), v::positive())->assert(42)); -exceptionFullMessage(static fn() => v::not(v::noneOf(v::intType(), v::positive()))->assert('-1')); -?> ---EXPECT-- -42 must not be an integer -"-1" must be an integer -- None of these rules must pass for 42 - - 42 must not be an integer - - 42 must not be a positive number -- All of these rules must pass for "-1" - - "-1" must be an integer - - "-1" must be a positive number \ No newline at end of file diff --git a/tests/integration/rules/notBlank.phpt b/tests/integration/rules/notBlank.phpt deleted file mode 100644 index 9bead4adc..000000000 --- a/tests/integration/rules/notBlank.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - v::notBlank()->assert(null)); -exceptionMessage(static fn() => v::notBlank()->setName('Field')->assert(null)); -exceptionMessage(static fn() => v::not(v::notBlank())->assert(1)); -exceptionFullMessage(static fn() => v::notBlank()->assert('')); -exceptionFullMessage(static fn() => v::notBlank()->setName('Field')->assert('')); -exceptionFullMessage(static fn() => v::not(v::notBlank())->assert([1])); -?> ---EXPECT-- -The value must not be blank -Field must not be blank -1 must be blank -- The value must not be blank -- Field must not be blank -- `[1]` must be blank diff --git a/tests/integration/rules/notEmoji.phpt b/tests/integration/rules/notEmoji.phpt deleted file mode 100644 index 90068105c..000000000 --- a/tests/integration/rules/notEmoji.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::notEmoji()->assert('🍕')); -exceptionMessage(static fn() => v::not(v::notEmoji())->assert('AB')); -exceptionFullMessage(static fn() => v::notEmoji()->assert('🏄')); -exceptionFullMessage(static fn() => v::not(v::notEmoji())->assert('YZ')); -?> ---EXPECT-- -"🍕" must not contain an emoji -"AB" must contain an emoji -- "🏄" must not contain an emoji -- "YZ" must contain an emoji \ No newline at end of file diff --git a/tests/integration/rules/notEmpty.phpt b/tests/integration/rules/notEmpty.phpt deleted file mode 100644 index 857f7e89f..000000000 --- a/tests/integration/rules/notEmpty.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - v::notEmpty()->assert(null)); -exceptionMessage(static fn() => v::notEmpty()->setName('Field')->assert(null)); -exceptionMessage(static fn() => v::not(v::notEmpty())->assert(1)); -exceptionFullMessage(static fn() => v::notEmpty()->assert('')); -exceptionFullMessage(static fn() => v::notEmpty()->setName('Field')->assert('')); -exceptionFullMessage(static fn() => v::not(v::notEmpty())->assert([1])); -?> ---EXPECT-- -The value must not be empty -Field must not be empty -1 must be empty -- The value must not be empty -- Field must not be empty -- `[1]` must be empty diff --git a/tests/integration/rules/notUndef.phpt b/tests/integration/rules/notUndef.phpt deleted file mode 100644 index a86660755..000000000 --- a/tests/integration/rules/notUndef.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::notUndef()->assert(null)); -exceptionMessage(static fn() => v::not(v::notUndef())->assert(0)); -exceptionMessage(static fn() => v::notUndef()->setName('Field')->assert(null)); -exceptionMessage(static fn() => v::not(v::notUndef()->setName('Field'))->assert([])); -exceptionFullMessage(static fn() => v::notUndef()->assert('')); -exceptionFullMessage(static fn() => v::not(v::notUndef())->assert([])); -exceptionFullMessage(static fn() => v::notUndef()->setName('Field')->assert('')); -exceptionFullMessage(static fn() => v::not(v::notUndef()->setName('Field'))->assert([])); -?> ---EXPECT-- -The value must be defined -The value must be undefined -Field must be defined -Field must be undefined -- The value must be defined -- The value must be undefined -- Field must be defined -- Field must be undefined \ No newline at end of file diff --git a/tests/integration/rules/nullOr.phpt b/tests/integration/rules/nullOr.phpt deleted file mode 100644 index b2ad3b829..000000000 --- a/tests/integration/rules/nullOr.phpt +++ /dev/null @@ -1,138 +0,0 @@ ---FILE-- - [v::nullOr(v::alpha()), 1234], - 'Inverted wrapper' => [v::not(v::nullOr(v::alpha())), 'alpha'], - 'Inverted wrapped' => [v::nullOr(v::not(v::alpha())), 'alpha'], - 'Inverted nullined' => [v::not(v::nullOr(v::alpha())), null], - 'Inverted nullined, wrapped name' => [v::not(v::nullOr(v::alpha()->setName('Wrapped'))), null], - 'Inverted nullined, wrapper name' => [v::not(v::nullOr(v::alpha())->setName('Wrapper')), null], - 'Inverted nullined, not name' => [v::not(v::nullOr(v::alpha()))->setName('Not'), null], - 'With template' => [v::nullOr(v::alpha()), 123, 'Nine nimble numismatists near Naples'], - 'With array template' => [v::nullOr(v::alpha()), 123, ['nullOrAlpha' => 'Next to nifty null notations']], - 'Inverted nullined with template' => [ - v::not(v::nullOr(v::alpha())), - null, - ['notNullOrAlpha' => 'Next to nifty null notations'], - ], - 'Without subsequent result' => [ - v::nullOr(v::alpha()->stringType()), - 1234, - ], - 'Without subsequent result with templates' => [ - v::nullOr(v::alpha()->stringType()), - 1234, - [ - 'nullOrAlpha' => 'Should be nul or alpha', - 'nullOrStringType' => 'Should be nul or string type', - ], - ], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -1234 must contain only letters (a-z) or must be null -- 1234 must contain only letters (a-z) or must be null -[ - 'nullOrAlpha' => '1234 must contain only letters (a-z) or must be null', -] - -Inverted wrapper -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"alpha" must not contain letters (a-z) and must not be null -- "alpha" must not contain letters (a-z) and must not be null -[ - 'notNullOrAlpha' => '"alpha" must not contain letters (a-z) and must not be null', -] - -Inverted wrapped -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"alpha" must not contain letters (a-z) or must be null -- "alpha" must not contain letters (a-z) or must be null -[ - 'nullOrNotAlpha' => '"alpha" must not contain letters (a-z) or must be null', -] - -Inverted nullined -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -`null` must not contain letters (a-z) and must not be null -- `null` must not contain letters (a-z) and must not be null -[ - 'notNullOrAlpha' => '`null` must not contain letters (a-z) and must not be null', -] - -Inverted nullined, wrapped name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not contain letters (a-z) and must not be null -- Wrapped must not contain letters (a-z) and must not be null -[ - 'notNullOrAlpha' => 'Wrapped must not contain letters (a-z) and must not be null', -] - -Inverted nullined, wrapper name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must not contain letters (a-z) and must not be null -- Wrapper must not contain letters (a-z) and must not be null -[ - 'notNullOrAlpha' => 'Wrapper must not contain letters (a-z) and must not be null', -] - -Inverted nullined, not name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not must not contain letters (a-z) and must not be null -- Not must not contain letters (a-z) and must not be null -[ - 'notNullOrAlpha' => 'Not must not contain letters (a-z) and must not be null', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Nine nimble numismatists near Naples -- Nine nimble numismatists near Naples -[ - 'nullOrAlpha' => 'Nine nimble numismatists near Naples', -] - -With array template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Next to nifty null notations -- Next to nifty null notations -[ - 'nullOrAlpha' => 'Next to nifty null notations', -] - -Inverted nullined with template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Next to nifty null notations -- Next to nifty null notations -[ - 'notNullOrAlpha' => 'Next to nifty null notations', -] - -Without subsequent result -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -1234 must contain only letters (a-z) or must be null -- All of the required rules must pass for 1234 - - 1234 must contain only letters (a-z) or must be null - - 1234 must be a string or must be null -[ - '__root__' => 'All of the required rules must pass for 1234', - 'nullOrAlpha' => '1234 must contain only letters (a-z) or must be null', - 'nullOrStringType' => '1234 must be a string or must be null', -] - -Without subsequent result with templates -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Should be nul or alpha -- All of the required rules must pass for 1234 - - Should be nul or alpha - - Should be nul or string type -[ - '__root__' => 'All of the required rules must pass for 1234', - 'nullOrAlpha' => 'Should be nul or alpha', - 'nullOrStringType' => 'Should be nul or string type', -] diff --git a/tests/integration/rules/nullType.phpt b/tests/integration/rules/nullType.phpt deleted file mode 100644 index e549ab0ea..000000000 --- a/tests/integration/rules/nullType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::nullType()->assert('')); -exceptionMessage(static fn() => v::not(v::nullType())->assert(null)); -exceptionFullMessage(static fn() => v::nullType()->assert(false)); -exceptionFullMessage(static fn() => v::not(v::nullType())->assert(null)); -?> ---EXPECT-- -"" must be null -`null` must not be null -- `false` must be null -- `null` must not be null diff --git a/tests/integration/rules/number.phpt b/tests/integration/rules/number.phpt deleted file mode 100644 index 25b5b98c9..000000000 --- a/tests/integration/rules/number.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::number()->assert(acos(1.01))); -exceptionMessage(static fn() => v::not(v::number())->assert(42)); -exceptionFullMessage(static fn() => v::number()->assert(NAN)); -exceptionFullMessage(static fn() => v::not(v::number())->assert(42)); -?> ---EXPECT-- -`NaN` must be a valid number -42 must not be a number -- `NaN` must be a valid number -- 42 must not be a number \ No newline at end of file diff --git a/tests/integration/rules/numericVal.phpt b/tests/integration/rules/numericVal.phpt deleted file mode 100644 index 4c6f357c1..000000000 --- a/tests/integration/rules/numericVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::numericVal()->assert('a')); -exceptionMessage(static fn() => v::not(v::numericVal())->assert('1')); -exceptionFullMessage(static fn() => v::numericVal()->assert('a')); -exceptionFullMessage(static fn() => v::not(v::numericVal())->assert('1')); -?> ---EXPECT-- -"a" must be a numeric value -"1" must not be a numeric value -- "a" must be a numeric value -- "1" must not be a numeric value \ No newline at end of file diff --git a/tests/integration/rules/objectType.phpt b/tests/integration/rules/objectType.phpt deleted file mode 100644 index 42177e968..000000000 --- a/tests/integration/rules/objectType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::objectType()->assert([])); -exceptionMessage(static fn() => v::not(v::objectType())->assert(new stdClass())); -exceptionFullMessage(static fn() => v::objectType()->assert('test')); -exceptionFullMessage(static fn() => v::not(v::objectType())->assert(new ArrayObject())); -?> ---EXPECT-- -`[]` must be an object -`stdClass {}` must not be an object -- "test" must be an object -- `ArrayObject { getArrayCopy() => [] }` must not be an object \ No newline at end of file diff --git a/tests/integration/rules/odd.phpt b/tests/integration/rules/odd.phpt deleted file mode 100644 index d0604afb0..000000000 --- a/tests/integration/rules/odd.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::odd()->assert(2)); -exceptionMessage(static fn() => v::not(v::odd())->assert(7)); -exceptionFullMessage(static fn() => v::odd()->assert(2)); -exceptionFullMessage(static fn() => v::not(v::odd())->assert(9)); -?> ---EXPECT-- -2 must be an odd number -7 must be an even number -- 2 must be an odd number -- 9 must be an even number \ No newline at end of file diff --git a/tests/integration/rules/perfectSquare.phpt b/tests/integration/rules/perfectSquare.phpt deleted file mode 100644 index eea3f98e8..000000000 --- a/tests/integration/rules/perfectSquare.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::perfectSquare()->assert(250)); -exceptionMessage(static fn() => v::not(v::perfectSquare())->assert(9)); -exceptionFullMessage(static fn() => v::perfectSquare()->assert(7)); -exceptionFullMessage(static fn() => v::not(v::perfectSquare())->assert(400)); -?> ---EXPECT-- -250 must be a perfect square number -9 must not be a perfect square number -- 7 must be a perfect square number -- 400 must not be a perfect square number \ No newline at end of file diff --git a/tests/integration/rules/pesel.phpt b/tests/integration/rules/pesel.phpt deleted file mode 100644 index 8834c7f5c..000000000 --- a/tests/integration/rules/pesel.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::pesel()->assert('21120209251')); -exceptionMessage(static fn() => v::not(v::pesel())->assert('21120209256')); -exceptionFullMessage(static fn() => v::pesel()->assert('21120209251')); -exceptionFullMessage(static fn() => v::not(v::pesel())->assert('21120209256')); -?> ---EXPECT--; -"21120209251" must be a valid PESEL -"21120209256" must not be a valid PESEL -- "21120209251" must be a valid PESEL -- "21120209256" must not be a valid PESEL diff --git a/tests/integration/rules/phone.phpt b/tests/integration/rules/phone.phpt deleted file mode 100644 index 07315003e..000000000 --- a/tests/integration/rules/phone.phpt +++ /dev/null @@ -1,53 +0,0 @@ ---FILE-- - [v::phone(), '123'], - 'Country-specific' => [v::phone('BR'), '+1 650 253 00 00'], - 'Inverted' => [v::not(v::phone()), '+55 11 91111 1111'], - 'Default with name' => [v::phone()->setName('Phone'), '123'], - 'Country-specific with name' => [v::phone('US')->setName('Phone'), '123'], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -"123" must be a valid telephone number -- "123" must be a valid telephone number -[ - 'phone' => '"123" must be a valid telephone number', -] - -Country-specific -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"+1 650 253 00 00" must be a valid telephone number for country Brazil -- "+1 650 253 00 00" must be a valid telephone number for country Brazil -[ - 'phone' => '"+1 650 253 00 00" must be a valid telephone number for country Brazil', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -"+55 11 91111 1111" must not be a valid telephone number -- "+55 11 91111 1111" must not be a valid telephone number -[ - 'notPhone' => '"+55 11 91111 1111" must not be a valid telephone number', -] - -Default with name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Phone must be a valid telephone number -- Phone must be a valid telephone number -[ - 'phone' => 'Phone must be a valid telephone number', -] - -Country-specific with name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Phone must be a valid telephone number for country United States -- Phone must be a valid telephone number for country United States -[ - 'phone' => 'Phone must be a valid telephone number for country United States', -] diff --git a/tests/integration/rules/phplabel.phpt b/tests/integration/rules/phplabel.phpt deleted file mode 100644 index a757fc573..000000000 --- a/tests/integration/rules/phplabel.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -PhpLabel rule exception should not be thrown for valid inputs ---FILE-- - v::phpLabel()->assert('f o o')); -exceptionMessage(static fn() => v::not(v::phpLabel())->assert('correctOne')); -exceptionFullMessage(static fn() => v::phpLabel()->assert('0wner')); -exceptionFullMessage(static fn() => v::not(v::phpLabel())->assert('Respect')); -?> ---EXPECT-- -"f o o" must be a valid PHP label -"correctOne" must not be a valid PHP label -- "0wner" must be a valid PHP label -- "Respect" must not be a valid PHP label diff --git a/tests/integration/rules/pis.phpt b/tests/integration/rules/pis.phpt deleted file mode 100644 index 6fe62e135..000000000 --- a/tests/integration/rules/pis.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::pis()->assert('this thing')); -exceptionMessage(static fn() => v::not(v::pis())->assert('120.6671.406-4')); -exceptionFullMessage(static fn() => v::pis()->assert('your mother')); -exceptionFullMessage(static fn() => v::not(v::pis())->assert('120.9378.174-5')); -?> ---EXPECT-- -"this thing" must be a valid PIS number -"120.6671.406-4" must not be a valid PIS number -- "your mother" must be a valid PIS number -- "120.9378.174-5" must not be a valid PIS number diff --git a/tests/integration/rules/polishIdCard.phpt b/tests/integration/rules/polishIdCard.phpt deleted file mode 100644 index 19f39d676..000000000 --- a/tests/integration/rules/polishIdCard.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::polishIdCard()->assert('AYE205411')); -exceptionMessage(static fn() => v::not(v::polishIdCard())->assert('AYE205410')); -exceptionFullMessage(static fn() => v::polishIdCard()->assert('AYE205411')); -exceptionFullMessage(static fn() => v::not(v::polishIdCard())->assert('AYE205410')); -?> ---EXPECT-- -"AYE205411" must be a valid Polish Identity Card number -"AYE205410" must not be a valid Polish Identity Card number -- "AYE205411" must be a valid Polish Identity Card number -- "AYE205410" must not be a valid Polish Identity Card number diff --git a/tests/integration/rules/positive.phpt b/tests/integration/rules/positive.phpt deleted file mode 100644 index 7c9f66339..000000000 --- a/tests/integration/rules/positive.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::positive()->assert(-10)); -exceptionMessage(static fn() => v::not(v::positive())->assert(16)); -exceptionFullMessage(static fn() => v::positive()->assert('a')); -exceptionFullMessage(static fn() => v::not(v::positive())->assert('165')); -?> ---EXPECT-- --10 must be a positive number -16 must not be a positive number -- "a" must be a positive number -- "165" must not be a positive number \ No newline at end of file diff --git a/tests/integration/rules/postalCode.phpt b/tests/integration/rules/postalCode.phpt deleted file mode 100644 index dbbc0de58..000000000 --- a/tests/integration/rules/postalCode.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::postalCode('BR')->assert('1057BV')); -exceptionMessage(static fn() => v::not(v::postalCode('NL'))->assert('1057BV')); -exceptionFullMessage(static fn() => v::postalCode('BR')->assert('1057BV')); -exceptionFullMessage(static fn() => v::not(v::postalCode('NL'))->assert('1057BV')); -?> ---EXPECT-- -"1057BV" must be a valid postal code on "BR" -"1057BV" must not be a valid postal code on "NL" -- "1057BV" must be a valid postal code on "BR" -- "1057BV" must not be a valid postal code on "NL" diff --git a/tests/integration/rules/primeNumber.phpt b/tests/integration/rules/primeNumber.phpt deleted file mode 100644 index 81ae03ea5..000000000 --- a/tests/integration/rules/primeNumber.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::primeNumber()->assert(10)); -exceptionMessage(static fn() => v::not(v::primeNumber())->assert(3)); -exceptionFullMessage(static fn() => v::primeNumber()->assert('Foo')); -exceptionFullMessage(static fn() => v::not(v::primeNumber())->assert('+7')); -?> ---EXPECT-- -10 must be a prime number -3 must not be a prime number -- "Foo" must be a prime number -- "+7" must not be a prime number \ No newline at end of file diff --git a/tests/integration/rules/printable.phpt b/tests/integration/rules/printable.phpt deleted file mode 100644 index 486b4df2c..000000000 --- a/tests/integration/rules/printable.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::printable()->assert('')); -exceptionMessage(static fn() => v::not(v::printable())->assert('abc')); -exceptionFullMessage(static fn() => v::printable()->assert('foo' . chr(10) . 'bar')); -exceptionFullMessage(static fn() => v::not(v::printable())->assert('$%asd')); -?> ---EXPECT-- -"" must contain only printable characters -"abc" must not contain printable characters -- "foo\nbar" must contain only printable characters -- "$%asd" must not contain printable characters diff --git a/tests/integration/rules/property.phpt b/tests/integration/rules/property.phpt deleted file mode 100644 index 8daa950af..000000000 --- a/tests/integration/rules/property.phpt +++ /dev/null @@ -1,162 +0,0 @@ ---FILE-- - [v::property('foo', v::intType()), new stdClass()], - 'Default' => [v::property('foo', v::intType()), (object) ['foo' => 'string']], - 'Inverted' => [v::not(v::property('foo', v::intType())), (object) ['foo' => 12]], - 'Double-inverted with missing property' => [ - v::not(v::not(v::property('foo', v::intType()))), - new stdClass(), - ], - - // With custom name - 'With wrapped name, missing property' => [ - v::property('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'), - new stdClass(), - ], - 'With wrapped name, default' => [ - v::property('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'), - (object) ['foo' => 'string'], - ], - 'With wrapped name, inverted' => [ - v::not(v::property('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not'), - (object) ['foo' => 12], - ], - 'With wrapper name, default' => [ - v::property('foo', v::intType())->setName('Wrapper'), - (object) ['foo' => 'string'], - ], - 'With wrapper name, missing property' => [ - v::property('foo', v::intType())->setName('Wrapper'), - new stdClass(), - ], - 'With wrapper name, inverted' => [ - v::not(v::property('foo', v::intType())->setName('Wrapper'))->setName('Not'), - (object) ['foo' => 12], - ], - 'With "Not" name, inverted' => [ - v::not(v::property('foo', v::intType()))->setName('Not'), - (object) ['foo' => 12], - ], - - // With custom template - 'With template, default' => [ - v::property('foo', v::intType()), - (object) ['foo' => 'string'], - 'Particularly precautions perplexing property', - ], - 'With template, inverted' => [ - v::not(v::property('foo', v::intType())), - (object) ['foo' => 12], - 'Not a prompt prospect of a particularly primitive property', - ], -]); -?> ---EXPECT-- -Missing property -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -Default -⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -Double-inverted with missing property -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -With wrapped name, missing property -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be present -- Wrapped must be present -[ - 'foo' => 'Wrapped must be present', -] - -With wrapped name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be an integer -- Wrapped must be an integer -[ - 'foo' => 'Wrapped must be an integer', -] - -With wrapped name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be an integer -- Wrapped must not be an integer -[ - 'foo' => 'Wrapped must not be an integer', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -With wrapper name, missing property -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With "Not" name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Particularly precautions perplexing property -- Particularly precautions perplexing property -[ - 'foo' => 'Particularly precautions perplexing property', -] - -With template, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not a prompt prospect of a particularly primitive property -- Not a prompt prospect of a particularly primitive property -[ - 'foo' => 'Not a prompt prospect of a particularly primitive property', -] diff --git a/tests/integration/rules/propertyExists.phpt b/tests/integration/rules/propertyExists.phpt deleted file mode 100644 index 72d8eb8d2..000000000 --- a/tests/integration/rules/propertyExists.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---FILE-- - [v::propertyExists('foo'), (object) ['bar' => 'baz']], - 'Inverted mode' => [v::not(v::propertyExists('foo')), (object) ['foo' => 'baz']], - 'Custom name' => [v::propertyExists('foo')->setName('Custom name'), (object) ['bar' => 'baz']], - 'Custom template' => [v::propertyExists('foo'), (object) ['bar' => 'baz'], 'Custom template for `{{name}}`'], -]); -?> ---EXPECT-- -Default mode -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -Inverted mode -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be present -- foo must not be present -[ - 'foo' => 'foo must not be present', -] - -Custom name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Custom name must be present -- Custom name must be present -[ - 'foo' => 'Custom name must be present', -] - -Custom template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Custom template for `foo` -- Custom template for `foo` -[ - 'foo' => 'Custom template for `foo`', -] diff --git a/tests/integration/rules/propertyOptional.phpt b/tests/integration/rules/propertyOptional.phpt deleted file mode 100644 index 0f69a6f42..000000000 --- a/tests/integration/rules/propertyOptional.phpt +++ /dev/null @@ -1,129 +0,0 @@ ---FILE-- - [v::propertyOptional('foo', v::intType()), (object) ['foo' => 'string']], - 'Inverted' => [v::not(v::propertyOptional('foo', v::intType())), (object) ['foo' => 12]], - 'Inverted with missing property' => [ - v::not(v::propertyOptional('foo', v::intType())), - new stdClass(), - ], - - // With custom name - 'With wrapped name, default' => [ - v::propertyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'), - (object) ['foo' => 'string'], - ], - 'With wrapped name, inverted' => [ - v::not(v::propertyOptional('foo', v::intType()->setName('Wrapped'))->setName('Wrapper'))->setName('Not'), - (object) ['foo' => 12], - ], - 'With wrapper name, default' => [ - v::propertyOptional('foo', v::intType())->setName('Wrapper'), - (object) ['foo' => 'string'], - ], - 'With wrapper name, inverted' => [ - v::not(v::propertyOptional('foo', v::intType())->setName('Wrapper'))->setName('Not'), - (object) ['foo' => 12], - ], - 'With "Not" name, inverted' => [ - v::not(v::propertyOptional('foo', v::intType()))->setName('Not'), - (object) ['foo' => 12], - ], - - // With custom template - 'With template, default' => [ - v::propertyOptional('foo', v::intType()), - (object) ['foo' => 'string'], - 'Proper property planners plan precise property plots', - ], - 'With template, inverted' => [ - v::not(v::propertyOptional('foo', v::intType())), - (object) ['foo' => 12], - 'Not proving prudent property planning promotes prosperity', - ], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -Inverted -⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -Inverted with missing property -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be present -- foo must be present -[ - 'foo' => 'foo must be present', -] - -With wrapped name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must be an integer -- Wrapped must be an integer -[ - 'foo' => 'Wrapped must be an integer', -] - -With wrapped name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not be an integer -- Wrapped must not be an integer -[ - 'foo' => 'Wrapped must not be an integer', -] - -With wrapper name, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be an integer -- foo must be an integer -[ - 'foo' => 'foo must be an integer', -] - -With wrapper name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With "Not" name, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -foo must not be an integer -- foo must not be an integer -[ - 'foo' => 'foo must not be an integer', -] - -With template, default -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Proper property planners plan precise property plots -- Proper property planners plan precise property plots -[ - 'foo' => 'Proper property planners plan precise property plots', -] - -With template, inverted -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not proving prudent property planning promotes prosperity -- Not proving prudent property planning promotes prosperity -[ - 'foo' => 'Not proving prudent property planning promotes prosperity', -] diff --git a/tests/integration/rules/punct.phpt b/tests/integration/rules/punct.phpt deleted file mode 100644 index b04fd08a9..000000000 --- a/tests/integration/rules/punct.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::punct()->assert('a')); -exceptionMessage(static fn() => v::punct('c')->assert('b')); -exceptionMessage(static fn() => v::not(v::punct())->assert('.')); -exceptionMessage(static fn() => v::not(v::punct('d'))->assert('?')); -exceptionFullMessage(static fn() => v::punct()->assert('e')); -exceptionFullMessage(static fn() => v::punct('f')->assert('g')); -exceptionFullMessage(static fn() => v::not(v::punct())->assert('!')); -exceptionFullMessage(static fn() => v::not(v::punct('h'))->assert(';')); -?> ---EXPECT-- -"a" must contain only punctuation characters -"b" must contain only punctuation characters and "c" -"." must not contain punctuation characters -"?" must not contain punctuation characters or "d" -- "e" must contain only punctuation characters -- "g" must contain only punctuation characters and "f" -- "!" must not contain punctuation characters -- ";" must not contain punctuation characters or "h" diff --git a/tests/integration/rules/readable.phpt b/tests/integration/rules/readable.phpt deleted file mode 100644 index a1dcb1cc7..000000000 --- a/tests/integration/rules/readable.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::readable()->assert('tests/fixtures/invalid-image.jpg')); -exceptionMessage(static fn() => v::not(v::readable())->assert('tests/fixtures/valid-image.png')); -exceptionFullMessage(static fn() => v::readable()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::readable())->assert('tests/fixtures/valid-image.png')); -?> ---EXPECT-- -"tests/fixtures/invalid-image.jpg" must be readable -"tests/fixtures/valid-image.png" must not be readable -- `stdClass {}` must be readable -- "tests/fixtures/valid-image.png" must not be readable diff --git a/tests/integration/rules/regex.phpt b/tests/integration/rules/regex.phpt deleted file mode 100644 index c6aebdba1..000000000 --- a/tests/integration/rules/regex.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::regex('/^w+$/')->assert('w poiur')); -exceptionMessage(static fn() => v::not(v::regex('/^[a-z]+$/'))->assert('wpoiur')); -exceptionFullMessage(static fn() => v::regex('/^w+$/')->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::regex('/^[a-z]+$/i'))->assert('wPoiur')); -?> ---EXPECT-- -"w poiur" must match the pattern `/^w+$/` -"wpoiur" must not match the pattern `/^[a-z]+$/` -- `stdClass {}` must match the pattern `/^w+$/` -- "wPoiur" must not match the pattern `/^[a-z]+$/i` \ No newline at end of file diff --git a/tests/integration/rules/resourceType.phpt b/tests/integration/rules/resourceType.phpt deleted file mode 100644 index 6b40baa3d..000000000 --- a/tests/integration/rules/resourceType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::resourceType()->assert('test')); -exceptionMessage(static fn() => v::not(v::resourceType())->assert(tmpfile())); -exceptionFullMessage(static fn() => v::resourceType()->assert([])); -exceptionFullMessage(static fn() => v::not(v::resourceType())->assert(tmpfile())); -?> ---EXPECT-- -"test" must be a resource -`resource ` must not be a resource -- `[]` must be a resource -- `resource ` must not be a resource diff --git a/tests/integration/rules/roman.phpt b/tests/integration/rules/roman.phpt deleted file mode 100644 index 5702ba4e8..000000000 --- a/tests/integration/rules/roman.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::roman()->assert(1234)); -exceptionMessage(static fn() => v::not(v::roman())->assert('XL')); -exceptionFullMessage(static fn() => v::roman()->assert('e2')); -exceptionFullMessage(static fn() => v::not(v::roman())->assert('IV')); -?> ---EXPECT-- -1234 must be a valid Roman numeral -"XL" must not be a valid Roman numeral -- "e2" must be a valid Roman numeral -- "IV" must not be a valid Roman numeral diff --git a/tests/integration/rules/scalarVal.phpt b/tests/integration/rules/scalarVal.phpt deleted file mode 100644 index f170e8e24..000000000 --- a/tests/integration/rules/scalarVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::scalarVal()->assert([])); -exceptionMessage(static fn() => v::not(v::scalarVal())->assert(true)); -exceptionFullMessage(static fn() => v::scalarVal()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::scalarVal())->assert(42)); -?> ---EXPECT-- -`[]` must be a scalar value -`true` must not be a scalar value -- `stdClass {}` must be a scalar value -- 42 must not be a scalar value diff --git a/tests/integration/rules/size.phpt b/tests/integration/rules/size.phpt deleted file mode 100644 index 1163ce122..000000000 --- a/tests/integration/rules/size.phpt +++ /dev/null @@ -1,31 +0,0 @@ ---FILE-- - v::size('1kb', '2kb')->assert('tests/fixtures/valid-image.gif')); -exceptionMessage(static fn() => v::size('700kb', null)->assert('tests/fixtures/valid-image.gif')); -exceptionMessage(static fn() => v::size(null, '1kb')->assert('tests/fixtures/valid-image.gif')); -exceptionMessage(static fn() => v::not(v::size('500kb', '600kb'))->assert('tests/fixtures/valid-image.gif')); -exceptionMessage(static fn() => v::not(v::size('500kb', null))->assert('tests/fixtures/valid-image.gif')); -exceptionMessage(static fn() => v::not(v::size(null, '600kb'))->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::size('1kb', '2kb')->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::size('700kb', null)->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::size(null, '1kb')->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::not(v::size('500kb', '600kb'))->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::not(v::size('500kb', null))->assert('tests/fixtures/valid-image.gif')); -exceptionFullMessage(static fn() => v::not(v::size(null, '600kb'))->assert('tests/fixtures/valid-image.gif')); -?> ---EXPECT-- -"tests/fixtures/valid-image.gif" must be between "1kb" and "2kb" -"tests/fixtures/valid-image.gif" must be greater than "700kb" -"tests/fixtures/valid-image.gif" must be lower than "1kb" -"tests/fixtures/valid-image.gif" must not be between "500kb" and "600kb" -"tests/fixtures/valid-image.gif" must not be greater than "500kb" -"tests/fixtures/valid-image.gif" must not be lower than "600kb" -- "tests/fixtures/valid-image.gif" must be between "1kb" and "2kb" -- "tests/fixtures/valid-image.gif" must be greater than "700kb" -- "tests/fixtures/valid-image.gif" must be lower than "1kb" -- "tests/fixtures/valid-image.gif" must not be between "500kb" and "600kb" -- "tests/fixtures/valid-image.gif" must not be greater than "500kb" -- "tests/fixtures/valid-image.gif" must not be lower than "600kb" diff --git a/tests/integration/rules/slug.phpt b/tests/integration/rules/slug.phpt deleted file mode 100644 index eb14898e4..000000000 --- a/tests/integration/rules/slug.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::slug()->assert('my-Slug')); -exceptionMessage(static fn() => v::not(v::slug())->assert('my-slug')); -exceptionFullMessage(static fn() => v::slug()->assert('my-Slug')); -exceptionFullMessage(static fn() => v::not(v::slug())->assert('my-slug')); -?> ---EXPECT-- -"my-Slug" must be a valid slug -"my-slug" must not be a valid slug -- "my-Slug" must be a valid slug -- "my-slug" must not be a valid slug diff --git a/tests/integration/rules/sorted.phpt b/tests/integration/rules/sorted.phpt deleted file mode 100644 index 46392be9c..000000000 --- a/tests/integration/rules/sorted.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::sorted('ASC')->assert([1, 3, 2])); -exceptionMessage(static fn() => v::sorted('DESC')->assert([1, 2, 3])); -exceptionMessage(static fn() => v::not(v::sorted('ASC'))->assert([1, 2, 3])); -exceptionMessage(static fn() => v::not(v::sorted('DESC'))->assert([3, 2, 1])); -exceptionFullMessage(static fn() => v::sorted('ASC')->assert([3, 2, 1])); -exceptionFullMessage(static fn() => v::sorted('DESC')->assert([1, 2, 3])); -exceptionFullMessage(static fn() => v::not(v::sorted('ASC'))->assert([1, 2, 3])); -exceptionFullMessage(static fn() => v::not(v::sorted('DESC'))->assert([3, 2, 1])); -?> ---EXPECT-- -`[1, 3, 2]` must be sorted in ascending order -`[1, 2, 3]` must be sorted in descending order -`[1, 2, 3]` must not be sorted in ascending order -`[3, 2, 1]` must not be sorted in descending order -- `[3, 2, 1]` must be sorted in ascending order -- `[1, 2, 3]` must be sorted in descending order -- `[1, 2, 3]` must not be sorted in ascending order -- `[3, 2, 1]` must not be sorted in descending order diff --git a/tests/integration/rules/space.phpt b/tests/integration/rules/space.phpt deleted file mode 100644 index f30a5dc7b..000000000 --- a/tests/integration/rules/space.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::space()->assert('ab')); -exceptionMessage(static fn() => v::space('c')->assert('cd')); -exceptionMessage(static fn() => v::not(v::space())->assert("\t")); -exceptionMessage(static fn() => v::not(v::space('def'))->assert("\r")); -exceptionFullMessage(static fn() => v::space()->assert('ef')); -exceptionFullMessage(static fn() => v::space('e')->assert('gh')); -exceptionFullMessage(static fn() => v::not(v::space())->assert("\n")); -exceptionFullMessage(static fn() => v::not(v::space('yk'))->assert(' k')); -?> ---EXPECT-- -"ab" must contain only space characters -"cd" must contain only space characters and "c" -"\t" must not contain space characters -"\r" must not contain space characters or "def" -- "ef" must contain only space characters -- "gh" must contain only space characters and "e" -- "\n" must not contain space characters -- " k" must not contain space characters or "yk" diff --git a/tests/integration/rules/startsWith.phpt b/tests/integration/rules/startsWith.phpt deleted file mode 100644 index 9783c3a87..000000000 --- a/tests/integration/rules/startsWith.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::startsWith('b')->assert(['a', 'b'])); -exceptionMessage(static fn() => v::not(v::startsWith(1.1))->assert([1.1, 2.2])); -exceptionFullMessage(static fn() => v::startsWith('3.3', true)->assert([3.3, 4.4])); -exceptionFullMessage(static fn() => v::not(v::startsWith('c'))->assert(['c', 'd'])); -?> ---EXPECT-- -`["a", "b"]` must start with "b" -`[1.1, 2.2]` must not start with 1.1 -- `[3.3, 4.4]` must start with "3.3" -- `["c", "d"]` must not start with "c" diff --git a/tests/integration/rules/stringType.phpt b/tests/integration/rules/stringType.phpt deleted file mode 100644 index 028e51f72..000000000 --- a/tests/integration/rules/stringType.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::stringType()->assert(42)); -exceptionMessage(static fn() => v::not(v::stringType())->assert('foo')); -exceptionFullMessage(static fn() => v::stringType()->assert(true)); -exceptionFullMessage(static fn() => v::not(v::stringType())->assert('bar')); -?> ---EXPECT-- -42 must be a string -"foo" must not be a string -- `true` must be a string -- "bar" must not be a string \ No newline at end of file diff --git a/tests/integration/rules/stringVal.phpt b/tests/integration/rules/stringVal.phpt deleted file mode 100644 index a1733e292..000000000 --- a/tests/integration/rules/stringVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::stringVal()->assert([])); -exceptionMessage(static fn() => v::not(v::stringVal())->assert(true)); -exceptionFullMessage(static fn() => v::stringVal()->assert(new stdClass())); -exceptionFullMessage(static fn() => v::not(v::stringVal())->assert(42)); -?> ---EXPECT-- -`[]` must be a string value -`true` must not be a string value -- `stdClass {}` must be a string value -- 42 must not be a string value \ No newline at end of file diff --git a/tests/integration/rules/subset.phpt b/tests/integration/rules/subset.phpt deleted file mode 100644 index c980b1d97..000000000 --- a/tests/integration/rules/subset.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::subset([1, 2])->assert([1, 2, 3])); -exceptionMessage(static fn() => v::not(v::subset([1, 2, 3]))->assert([1, 2])); -exceptionFullMessage(static fn() => v::subset(['A', 'B'])->assert(['B', 'C'])); -exceptionFullMessage(static fn() => v::not(v::subset(['A']))->assert(['A'])); -?> ---EXPECT-- -`[1, 2, 3]` must be subset of `[1, 2]` -`[1, 2]` must not be subset of `[1, 2, 3]` -- `["B", "C"]` must be subset of `["A", "B"]` -- `["A"]` must not be subset of `["A"]` diff --git a/tests/integration/rules/symbolicLink.phpt b/tests/integration/rules/symbolicLink.phpt deleted file mode 100644 index 014d5d148..000000000 --- a/tests/integration/rules/symbolicLink.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::symbolicLink()->assert('tests/fixtures/fake-filename')); -exceptionMessage(static fn() => v::not(v::symbolicLink())->assert('tests/fixtures/symbolic-link')); -exceptionFullMessage(static fn() => v::symbolicLink()->assert('tests/fixtures/fake-filename')); -exceptionFullMessage(static fn() => v::not(v::symbolicLink())->assert('tests/fixtures/symbolic-link')); -?> ---EXPECT-- -"tests/fixtures/fake-filename" must be a symbolic link -"tests/fixtures/symbolic-link" must not be a symbolic link -- "tests/fixtures/fake-filename" must be a symbolic link -- "tests/fixtures/symbolic-link" must not be a symbolic link diff --git a/tests/integration/rules/time.phpt b/tests/integration/rules/time.phpt deleted file mode 100644 index d4e1c2aa3..000000000 --- a/tests/integration/rules/time.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---FILE-- - v::time()->assert('2018-01-30')); -exceptionMessage(static fn() => v::not(v::time())->assert('09:25:46')); -exceptionFullMessage(static fn() => v::time()->assert('2018-01-30')); -exceptionFullMessage(static fn() => v::not(v::time('g:i A'))->assert('8:13 AM')); -?> ---EXPECT-- -"2018-01-30" must be a valid time in the format "23:59:59" -"09:25:46" must not be a valid time in the format "23:59:59" -- "2018-01-30" must be a valid time in the format "23:59:59" -- "8:13 AM" must not be a valid time in the format "11:59 PM" diff --git a/tests/integration/rules/tld.phpt b/tests/integration/rules/tld.phpt deleted file mode 100644 index 813af4b64..000000000 --- a/tests/integration/rules/tld.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::tld()->assert('42')); -exceptionMessage(static fn() => v::not(v::tld())->assert('com')); -exceptionFullMessage(static fn() => v::tld()->assert('1984')); -exceptionFullMessage(static fn() => v::not(v::tld())->assert('com')); -?> ---EXPECT-- -"42" must be a valid top-level domain name -"com" must not be a valid top-level domain name -- "1984" must be a valid top-level domain name -- "com" must not be a valid top-level domain name diff --git a/tests/integration/rules/trueVal.phpt b/tests/integration/rules/trueVal.phpt deleted file mode 100644 index 6d6d487bd..000000000 --- a/tests/integration/rules/trueVal.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::trueVal()->assert(false)); -exceptionMessage(static fn() => v::not(v::trueVal())->assert(1)); -exceptionFullMessage(static fn() => v::trueVal()->assert(0)); -exceptionFullMessage(static fn() => v::not(v::trueVal())->assert('true')); -?> ---EXPECT-- -`false` must evaluate to `true` -1 must not evaluate to `true` -- 0 must evaluate to `true` -- "true" must not evaluate to `true` diff --git a/tests/integration/rules/undefOr.phpt b/tests/integration/rules/undefOr.phpt deleted file mode 100644 index c6d9581b5..000000000 --- a/tests/integration/rules/undefOr.phpt +++ /dev/null @@ -1,138 +0,0 @@ ---FILE-- - [v::undefOr(v::alpha()), 1234], - 'Inverted wrapper' => [v::not(v::undefOr(v::alpha())), 'alpha'], - 'Inverted wrapped' => [v::undefOr(v::not(v::alpha())), 'alpha'], - 'Inverted undefined' => [v::not(v::undefOr(v::alpha())), null], - 'Inverted undefined, wrapped name' => [v::not(v::undefOr(v::alpha()->setName('Wrapped'))), null], - 'Inverted undefined, wrapper name' => [v::not(v::undefOr(v::alpha())->setName('Wrapper')), null], - 'Inverted undefined, not name' => [v::not(v::undefOr(v::alpha()))->setName('Not'), null], - 'With template' => [v::undefOr(v::alpha()), 123, 'Underneath the undulating umbrella'], - 'With array template' => [v::undefOr(v::alpha()), 123, ['undefOrAlpha' => 'Undefined number of unique unicorns']], - 'Inverted undefined with template' => [ - v::not(v::undefOr(v::alpha())), - '', - ['notUndefOrAlpha' => 'Should not be undefined or alpha'], - ], - 'Without subsequent result' => [ - v::undefOr(v::alpha()->stringType()), - 1234, - ], - 'Without subsequent result with templates' => [ - v::undefOr(v::alpha()->stringType()), - 1234, - [ - 'undefOrAlpha' => 'Should be nul or alpha', - 'undefOrStringType' => 'Should be nul or string type', - ], - ], -]); -?> ---EXPECT-- -Default -⎺⎺⎺⎺⎺⎺⎺ -1234 must contain only letters (a-z) or must be undefined -- 1234 must contain only letters (a-z) or must be undefined -[ - 'undefOrAlpha' => '1234 must contain only letters (a-z) or must be undefined', -] - -Inverted wrapper -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"alpha" must not contain letters (a-z) and must not be undefined -- "alpha" must not contain letters (a-z) and must not be undefined -[ - 'notUndefOrAlpha' => '"alpha" must not contain letters (a-z) and must not be undefined', -] - -Inverted wrapped -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -"alpha" must not contain letters (a-z) or must be undefined -- "alpha" must not contain letters (a-z) or must be undefined -[ - 'undefOrNotAlpha' => '"alpha" must not contain letters (a-z) or must be undefined', -] - -Inverted undefined -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -`null` must not contain letters (a-z) and must not be undefined -- `null` must not contain letters (a-z) and must not be undefined -[ - 'notUndefOrAlpha' => '`null` must not contain letters (a-z) and must not be undefined', -] - -Inverted undefined, wrapped name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapped must not contain letters (a-z) and must not be undefined -- Wrapped must not contain letters (a-z) and must not be undefined -[ - 'notUndefOrAlpha' => 'Wrapped must not contain letters (a-z) and must not be undefined', -] - -Inverted undefined, wrapper name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Wrapper must not contain letters (a-z) and must not be undefined -- Wrapper must not contain letters (a-z) and must not be undefined -[ - 'notUndefOrAlpha' => 'Wrapper must not contain letters (a-z) and must not be undefined', -] - -Inverted undefined, not name -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not must not contain letters (a-z) and must not be undefined -- Not must not contain letters (a-z) and must not be undefined -[ - 'notUndefOrAlpha' => 'Not must not contain letters (a-z) and must not be undefined', -] - -With template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Underneath the undulating umbrella -- Underneath the undulating umbrella -[ - 'undefOrAlpha' => 'Underneath the undulating umbrella', -] - -With array template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Undefined number of unique unicorns -- Undefined number of unique unicorns -[ - 'undefOrAlpha' => 'Undefined number of unique unicorns', -] - -Inverted undefined with template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Should not be undefined or alpha -- Should not be undefined or alpha -[ - 'notUndefOrAlpha' => 'Should not be undefined or alpha', -] - -Without subsequent result -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -1234 must contain only letters (a-z) or must be undefined -- All of the required rules must pass for 1234 - - 1234 must contain only letters (a-z) or must be undefined - - 1234 must be a string or must be undefined -[ - '__root__' => 'All of the required rules must pass for 1234', - 'undefOrAlpha' => '1234 must contain only letters (a-z) or must be undefined', - 'undefOrStringType' => '1234 must be a string or must be undefined', -] - -Without subsequent result with templates -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Should be nul or alpha -- All of the required rules must pass for 1234 - - Should be nul or alpha - - Should be nul or string type -[ - '__root__' => 'All of the required rules must pass for 1234', - 'undefOrAlpha' => 'Should be nul or alpha', - 'undefOrStringType' => 'Should be nul or string type', -] diff --git a/tests/integration/rules/unique.phpt b/tests/integration/rules/unique.phpt deleted file mode 100644 index 64f921c70..000000000 --- a/tests/integration/rules/unique.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::unique()->assert([1, 2, 2, 3])); -exceptionMessage(static fn() => v::not(v::unique())->assert([1, 2, 3, 4])); -exceptionFullMessage(static fn() => v::unique()->assert('test')); -exceptionFullMessage(static fn() => v::not(v::unique())->assert(['a', 'b', 'c'])); -?> ---EXPECT-- -`[1, 2, 2, 3]` must not contain duplicates -`[1, 2, 3, 4]` must contain duplicates -- "test" must not contain duplicates -- `["a", "b", "c"]` must contain duplicates diff --git a/tests/integration/rules/uploaded.phpt b/tests/integration/rules/uploaded.phpt deleted file mode 100644 index 9208f2cc3..000000000 --- a/tests/integration/rules/uploaded.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---FILE-- - v::uploaded()->assert('filename')); -uopz_set_return('is_uploaded_file', true); -exceptionMessage(static fn() => v::not(v::uploaded())->assert('filename')); -uopz_set_return('is_uploaded_file', false); -exceptionFullMessage(static fn() => v::uploaded()->assert('filename')); -uopz_set_return('is_uploaded_file', true); -exceptionFullMessage(static fn() => v::not(v::uploaded())->assert('filename'));?> ---SKIPIF-- - ---EXPECT-- -"filename" must be an uploaded file -"filename" must not be an uploaded file -- "filename" must be an uploaded file -- "filename" must not be an uploaded file diff --git a/tests/integration/rules/uppercase.phpt b/tests/integration/rules/uppercase.phpt deleted file mode 100644 index da486d07e..000000000 --- a/tests/integration/rules/uppercase.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::uppercase()->assert('lowercase')); -exceptionFullMessage(static fn() => v::uppercase()->assert('lowercase')); -exceptionMessage(static fn() => v::not(v::uppercase())->assert('UPPERCASE')); -exceptionFullMessage(static fn() => v::not(v::uppercase())->assert('UPPERCASE')); -?> ---EXPECT-- -"lowercase" must contain only uppercase letters -- "lowercase" must contain only uppercase letters -"UPPERCASE" must not contain only uppercase letters -- "UPPERCASE" must not contain only uppercase letters \ No newline at end of file diff --git a/tests/integration/rules/url.phpt b/tests/integration/rules/url.phpt deleted file mode 100644 index 34be58a6e..000000000 --- a/tests/integration/rules/url.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::url()->assert('example.com')); -exceptionMessage(static fn() => v::not(v::url())->assert('http://example.com')); -exceptionFullMessage(static fn() => v::url()->assert('example.com')); -exceptionFullMessage(static fn() => v::not(v::url())->assert('http://example.com')); -?> ---EXPECT-- -"example.com" must be a URL -"http://example.com" must not be a URL -- "example.com" must be a URL -- "http://example.com" must not be a URL diff --git a/tests/integration/rules/uuid.phpt b/tests/integration/rules/uuid.phpt deleted file mode 100644 index 4c9f14df8..000000000 --- a/tests/integration/rules/uuid.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::uuid()->assert('g71a18f4-3a13-11e7-a919-92ebcb67fe33')); -exceptionMessage(static fn() => v::uuid(1)->assert('e0b5ffb9-9caf-2a34-9673-8fc91db78be6')); -exceptionMessage(static fn() => v::not(v::uuid())->assert('fb3a7909-8034-59f5-8f38-21adbc168db7')); -exceptionMessage(static fn() => v::not(v::uuid(3))->assert('11a38b9a-b3da-360f-9353-a5a725514269')); -exceptionFullMessage(static fn() => v::uuid()->assert('g71a18f4-3a13-11e7-a919-92ebcb67fe33')); -exceptionFullMessage(static fn() => v::uuid(4)->assert('a71a18f4-3a13-11e7-a919-92ebcb67fe33')); -exceptionFullMessage(static fn() => v::not(v::uuid())->assert('e0b5ffb9-9caf-4a34-9673-8fc91db78be6')); -exceptionFullMessage(static fn() => v::not(v::uuid(5))->assert('c4a760a8-dbcf-5254-a0d9-6a4474bd1b62')); -?> ---EXPECT-- -"g71a18f4-3a13-11e7-a919-92ebcb67fe33" must be a valid UUID -"e0b5ffb9-9caf-2a34-9673-8fc91db78be6" must be a valid UUID version 1 -"fb3a7909-8034-59f5-8f38-21adbc168db7" must not be a valid UUID -"11a38b9a-b3da-360f-9353-a5a725514269" must not be a valid UUID version 3 -- "g71a18f4-3a13-11e7-a919-92ebcb67fe33" must be a valid UUID -- "a71a18f4-3a13-11e7-a919-92ebcb67fe33" must be a valid UUID version 4 -- "e0b5ffb9-9caf-4a34-9673-8fc91db78be6" must not be a valid UUID -- "c4a760a8-dbcf-5254-a0d9-6a4474bd1b62" must not be a valid UUID version 5 diff --git a/tests/integration/rules/version.phpt b/tests/integration/rules/version.phpt deleted file mode 100644 index 6e3261c3c..000000000 --- a/tests/integration/rules/version.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::version()->assert('1.3.7--')); -exceptionMessage(static fn() => v::not(v::version())->assert('1.0.0-alpha')); -exceptionFullMessage(static fn() => v::version()->assert('1.2.3.4-beta')); -exceptionFullMessage(static fn() => v::not(v::version())->assert('1.3.7-rc.1')); -?> ---EXPECT-- -"1.3.7--" must be a version -"1.0.0-alpha" must not be a version -- "1.2.3.4-beta" must be a version -- "1.3.7-rc.1" must not be a version diff --git a/tests/integration/rules/videoUrl.phpt b/tests/integration/rules/videoUrl.phpt deleted file mode 100644 index 314795ce7..000000000 --- a/tests/integration/rules/videoUrl.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::videoUrl()->assert('example.com')); -exceptionMessage(static fn() => v::videoUrl('YouTube')->assert('example.com')); -exceptionMessage(static fn() => v::not(v::videoUrl())->assert('https://player.vimeo.com/video/7178746722')); -exceptionMessage(static fn() => v::not(v::videoUrl('YouTube'))->assert('https://www.youtube.com/embed/netHLn9TScY')); -exceptionFullMessage(static fn() => v::videoUrl()->assert('example.com')); -exceptionFullMessage(static fn() => v::videoUrl('Vimeo')->assert('example.com')); -exceptionFullMessage(static fn() => v::not(v::videoUrl())->assert('https://youtu.be/netHLn9TScY')); -exceptionFullMessage(static fn() => v::not(v::videoUrl('Vimeo'))->assert('https://vimeo.com/71787467')); -?> ---EXPECT-- -"example.com" must be a valid video URL -"example.com" must be a valid YouTube video URL -"https://player.vimeo.com/video/7178746722" must not be a valid video URL -"https://www.youtube.com/embed/netHLn9TScY" must not be a valid YouTube video URL -- "example.com" must be a valid video URL -- "example.com" must be a valid Vimeo video URL -- "https://youtu.be/netHLn9TScY" must not be a valid video URL -- "https://vimeo.com/71787467" must not be a valid Vimeo video URL diff --git a/tests/integration/rules/vowel.phpt b/tests/integration/rules/vowel.phpt deleted file mode 100644 index 61b6831c1..000000000 --- a/tests/integration/rules/vowel.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::vowel()->assert('b')); -exceptionMessage(static fn() => v::vowel('c')->assert('d')); -exceptionMessage(static fn() => v::not(v::vowel())->assert('a')); -exceptionMessage(static fn() => v::not(v::vowel('f'))->assert('e')); -exceptionFullMessage(static fn() => v::vowel()->assert('g')); -exceptionFullMessage(static fn() => v::vowel('h')->assert('j')); -exceptionFullMessage(static fn() => v::not(v::vowel())->assert('i')); -exceptionFullMessage(static fn() => v::not(v::vowel('k'))->assert('o')); -?> ---EXPECT-- -"b" must consist of vowels only -"d" must consist of vowels and "c" -"a" must not consist of vowels only -"e" must not consist of vowels or "f" -- "g" must consist of vowels only -- "j" must consist of vowels and "h" -- "i" must not consist of vowels only -- "o" must not consist of vowels or "k" \ No newline at end of file diff --git a/tests/integration/rules/when.phpt b/tests/integration/rules/when.phpt deleted file mode 100644 index 4f610408f..000000000 --- a/tests/integration/rules/when.phpt +++ /dev/null @@ -1,84 +0,0 @@ ---FILE-- - [v::when(v::intVal(), v::positive(), v::notEmpty()), -1], - 'When invalid use "else"' => [v::when(v::intVal(), v::positive(), v::notEmpty()), ''], - 'When valid use "then" using single template' => [ - v::when(v::intVal(), v::positive(), v::notEmpty()), - -1, - 'That did not go as planned', - ], - 'When invalid use "else" using single template' => [ - v::when(v::intVal(), v::positive(), v::notEmpty()), - '', - 'That could have been better', - ], - 'When valid use "then" using array template' => [ - v::when(v::intVal(), v::positive(), v::notEmpty()), - -1, - [ - 'notEmpty' => '--Never shown--', - 'positive' => 'Not positive', - ], - ], - 'When invalid use "else" using array template' => [ - v::when(v::intVal(), v::positive(), v::notEmpty()), - '', - [ - 'notEmpty' => 'Not empty', - 'positive' => '--Never shown--', - ], - ], -]); -?> ---EXPECT-- -When valid use "then" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ --1 must be a positive number -- -1 must be a positive number -[ - 'positive' => '-1 must be a positive number', -] - -When invalid use "else" -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -The value must not be empty -- The value must not be empty -[ - 'notEmpty' => 'The value must not be empty', -] - -When valid use "then" using single template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -That did not go as planned -- That did not go as planned -[ - 'positive' => 'That did not go as planned', -] - -When invalid use "else" using single template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -That could have been better -- That could have been better -[ - 'notEmpty' => 'That could have been better', -] - -When valid use "then" using array template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not positive -- Not positive -[ - 'positive' => 'Not positive', -] - -When invalid use "else" using array template -⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺⎺ -Not empty -- Not empty -[ - 'notEmpty' => 'Not empty', -] diff --git a/tests/integration/rules/writable.phpt b/tests/integration/rules/writable.phpt deleted file mode 100644 index 2086426e6..000000000 --- a/tests/integration/rules/writable.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::writable()->assert('/path/of/a/valid/writable/file.txt')); -exceptionMessage(static fn() => v::not(v::writable())->assert('tests/fixtures/valid-image.png')); -exceptionFullMessage(static fn() => v::writable()->assert([])); -exceptionFullMessage(static fn() => v::not(v::writable())->assert('tests/fixtures/invalid-image.png')); -?> ---EXPECT-- -"/path/of/a/valid/writable/file.txt" must be writable -"tests/fixtures/valid-image.png" must not be writable -- `[]` must be writable -- "tests/fixtures/invalid-image.png" must not be writable diff --git a/tests/integration/rules/xdigit.phpt b/tests/integration/rules/xdigit.phpt deleted file mode 100644 index 6a5533b6d..000000000 --- a/tests/integration/rules/xdigit.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::xdigit()->assert('aaa%a')); -exceptionMessage(static fn() => v::xdigit(' ')->assert('bbb%b')); -exceptionMessage(static fn() => v::not(v::xdigit())->assert('ccccc')); -exceptionMessage(static fn() => v::not(v::xdigit('% '))->assert('ddd%d')); -exceptionFullMessage(static fn() => v::xdigit()->assert('eee^e')); -exceptionFullMessage(static fn() => v::not(v::xdigit())->assert('fffff')); -exceptionFullMessage(static fn() => v::xdigit('* &%')->assert('000^0')); -exceptionFullMessage(static fn() => v::not(v::xdigit('^'))->assert('111^1')); -?> ---EXPECT-- -"aaa%a" must only contain hexadecimal digits -"bbb%b" must contain hexadecimal digits and " " -"ccccc" must not only contain hexadecimal digits -"ddd%d" must not contain hexadecimal digits or "% " -- "eee^e" must only contain hexadecimal digits -- "fffff" must not only contain hexadecimal digits -- "000^0" must contain hexadecimal digits and "* &%" -- "111^1" must not contain hexadecimal digits or "^" \ No newline at end of file diff --git a/tests/integration/rules/yes.phpt b/tests/integration/rules/yes.phpt deleted file mode 100644 index 055d3ee68..000000000 --- a/tests/integration/rules/yes.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---FILE-- - v::not(v::yes())->assert('Yes')); -exceptionMessage(static fn() => v::yes()->assert('si')); -exceptionFullMessage(static fn() => v::not(v::yes())->assert('Yes')); -exceptionFullMessage(static fn() => v::yes()->assert('si')); -?> ---EXPECT-- -"Yes" must not be similar to "Yes" -"si" must be similar to "Yes" -- "Yes" must not be similar to "Yes" -- "si" must be similar to "Yes" diff --git a/tests/integration/set_template_with_multiple_validators_should_use_template_as_full_message.phpt b/tests/integration/set_template_with_multiple_validators_should_use_template_as_full_message.phpt deleted file mode 100644 index 882b83493..000000000 --- a/tests/integration/set_template_with_multiple_validators_should_use_template_as_full_message.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---FILE-- -between(1, 2)->setTemplate('{{name}} is not tasty')->assert('something'); -}); -?> ---EXPECT-- -- "something" is not tasty diff --git a/tests/integration/set_template_with_multiple_validators_should_use_template_as_main_message.phpt b/tests/integration/set_template_with_multiple_validators_should_use_template_as_main_message.phpt deleted file mode 100644 index 3d1c3ea6d..000000000 --- a/tests/integration/set_template_with_multiple_validators_should_use_template_as_main_message.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -setTemplate() with multiple validators should use template as main message ---FILE-- -between(1, 2)->setTemplate('{{name}} is not tasty')->assert('something'); -}); -?> ---EXPECT-- -"something" is not tasty diff --git a/tests/integration/set_template_with_single_validator_should_use_template_as_main_message.phpt b/tests/integration/set_template_with_single_validator_should_use_template_as_main_message.phpt deleted file mode 100644 index 7cea4c755..000000000 --- a/tests/integration/set_template_with_single_validator_should_use_template_as_main_message.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -setTemplate() with single validator should use template as main message ---FILE-- -setTemplate('{{name}} is not tasty'); - -exceptionMessage(static fn() => $rule->assert('something')); -exceptionMessage(static fn() => $rule->assert('something')); -?> ---EXPECT-- -"something" is not tasty -"something" is not tasty diff --git a/tests/integration/should_not_overwrite_defined_names.phpt b/tests/integration/should_not_overwrite_defined_names.phpt deleted file mode 100644 index eb4f03587..000000000 --- a/tests/integration/should_not_overwrite_defined_names.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---FILE-- - 'not an email']; - -exceptionMessage(static fn() => v::key('email', v::email()->setName('Email'))->setName('Foo')->assert($input)); - -// This is a trick thing: the call to `setName()` here seems to be the one -// from the `Key` rule but it's actually from the `Validator`. -exceptionMessage(static fn() => v::key('email', v::email())->setName('Email')->assert($input)); - -exceptionMessage(static fn() => v::key('email', v::email())->assert($input)); -?> ---EXPECT-- -Email must be a valid email address -email must be a valid email address -email must be a valid email address \ No newline at end of file diff --git a/tests/integration/transformers/aliases.phpt b/tests/integration/transformers/aliases.phpt deleted file mode 100644 index 0fcb669c9..000000000 --- a/tests/integration/transformers/aliases.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---FILE-- - [v::optional(v::scalarVal()), []], -]); -?> ---EXPECT-- -optional -⎺⎺⎺⎺⎺⎺⎺⎺ -`[]` must be a scalar value or must be undefined -- `[]` must be a scalar value or must be undefined -[ - 'undefOrScalarVal' => '`[]` must be a scalar value or must be undefined', -] diff --git a/tests/integration/transformers/deprecated_age.phpt b/tests/integration/transformers/deprecated_age.phpt deleted file mode 100644 index b0f569783..000000000 --- a/tests/integration/transformers/deprecated_age.phpt +++ /dev/null @@ -1,41 +0,0 @@ ---FILE-- - v::minAge(18)->assert('17 years ago')); -exceptionMessage(static fn() => v::not(v::minAge(18))->assert('-30 years')); -exceptionFullMessage(static fn() => v::minAge(18)->assert('yesterday')); -exceptionFullMessage(static fn() => v::minAge(18, 'd/m/Y')->assert('12/10/2010')); -exceptionMessage(static fn() => v::maxAge(12)->assert('50 years ago')); -exceptionMessage(static fn() => v::not(v::maxAge(12))->assert('11 years ago')); -exceptionFullMessage(static fn() => v::maxAge(12, 'Y-m-d')->assert('1988-09-09')); -exceptionFullMessage(static fn() => v::not(v::maxAge(12, 'Y-m-d'))->assert('2018-01-01')); -?> ---EXPECTF-- - -Deprecated: The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -The number of years between now and 17 years ago must be greater than or equal to 18 - -Deprecated: The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -The number of years between now and -30 years must be less than 18 - -Deprecated: The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -- The number of years between now and yesterday must be greater than or equal to 18 - -Deprecated: The minAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -- The number of years between now and %d/%d/%d must be greater than or equal to 18 - -Deprecated: The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -The number of years between now and 50 years ago must be less than or equal to 12 - -Deprecated: The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -The number of years between now and 11 years ago must be greater than 12 - -Deprecated: The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -- The number of years between now and %d-%d-%d must be less than or equal to 12 - -Deprecated: The maxAge() rule has been deprecated and will be removed in the next major version. Use dateTimeDiff() instead. %s -- The number of years between now and %d-%d-%d must be greater than 12 diff --git a/tests/integration/transformers/deprecated_attribute.phpt b/tests/integration/transformers/deprecated_attribute.phpt deleted file mode 100644 index 42b390f5d..000000000 --- a/tests/integration/transformers/deprecated_attribute.phpt +++ /dev/null @@ -1,43 +0,0 @@ ---FILE-- -foo = true; -$object->bar = 42; - -exceptionMessage(static fn() => v::attribute('baz')->assert($object)); -exceptionMessage(static fn() => v::not(v::attribute('foo'))->assert($object)); -exceptionMessage(static fn() => v::attribute('foo', v::falseVal())->assert($object)); -exceptionMessage(static fn() => v::not(v::attribute('foo', v::trueVal()))->assert($object)); -exceptionMessage(static fn() => v::attribute('foo', v::falseVal(), true)->assert($object)); -exceptionMessage(static fn() => v::not(v::attribute('foo', v::trueVal(), true))->assert($object)); -exceptionMessage(static fn() => v::attribute('foo', v::falseVal(), false)->assert($object)); -exceptionMessage(static fn() => v::not(v::attribute('foo', v::trueVal(), false))->assert($object)); -?> ---EXPECTF-- - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use propertyExists() instead. %s -baz must be present - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use propertyExists() instead. %s -foo must not be present - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use property() instead. %s -foo must evaluate to `false` - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use property() instead. %s -foo must not evaluate to `true` - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use property() without it. %s -foo must evaluate to `false` - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use property() without it. %s -foo must not evaluate to `true` - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use propertyOptional() instead. %s -foo must evaluate to `false` - -Deprecated: The attribute() rule has been deprecated and will be removed in the next major version. Use propertyOptional() instead. %s -foo must not evaluate to `true` diff --git a/tests/integration/transformers/deprecated_key.phpt b/tests/integration/transformers/deprecated_key.phpt deleted file mode 100644 index 63e871687..000000000 --- a/tests/integration/transformers/deprecated_key.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---FILE-- - true, 'bar' => 42]; - -exceptionMessage(static fn() => v::key('baz')->assert($array)); -exceptionMessage(static fn() => v::not(v::key('foo'))->assert($array)); -exceptionMessage(static fn() => v::key('foo', v::falseVal(), true)->assert($array)); -exceptionMessage(static fn() => v::not(v::key('foo', v::trueVal(), true))->assert($array)); -exceptionMessage(static fn() => v::key('foo', v::falseVal(), false)->assert($array)); -exceptionMessage(static fn() => v::not(v::key('foo', v::trueVal(), false))->assert($array)); -?> ---EXPECTF-- - -Deprecated: Calling key() without a second parameter has been deprecated, and will be not be allowed in the next major version. Use keyExists() instead. %s -baz must be present - -Deprecated: Calling key() without a second parameter has been deprecated, and will be not be allowed in the next major version. Use keyExists() instead. %s -foo must not be present - -Deprecated: Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use key() without it the third parameter. %s -foo must evaluate to `false` - -Deprecated: Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use key() without it the third parameter. %s -foo must not evaluate to `true` - -Deprecated: Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use keyOptional() instead. %s -foo must evaluate to `false` - -Deprecated: Calling key() with a third parameter has been deprecated, and will be not be allowed in the next major version. Use keyOptional() instead. %s -foo must not evaluate to `true` diff --git a/tests/integration/transformers/deprecated_keyNested.phpt b/tests/integration/transformers/deprecated_keyNested.phpt deleted file mode 100644 index adc540a74..000000000 --- a/tests/integration/transformers/deprecated_keyNested.phpt +++ /dev/null @@ -1,45 +0,0 @@ ---FILE-- - (object) [ - 'bar' => 123, - ], -]; - -exceptionMessage(static fn() => v::keyNested('foo.bar.baz')->assert(['foo.bar.baz' => false])); -exceptionMessage(static fn() => v::keyNested('foo.bar')->assert($input)); -exceptionMessage(static fn() => v::keyNested('foo.bar')->assert(new ArrayObject($input))); -exceptionMessage(static fn() => v::keyNested('foo.bar', v::negative())->assert($input)); -exceptionMessage(static fn() => v::keyNested('foo.bar')->assert($input)); -exceptionMessage(static fn() => v::keyNested('foo.bar', v::stringType())->assert($input)); -exceptionMessage(static fn() => v::keyNested('foo.bar.baz', v::notEmpty(), false)->assert($input)); -exceptionMessage(static fn() => v::keyNested('foo.bar', v::floatType(), false)->assert($input)); -?> ---EXPECTF-- - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -foo must be present - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -No exception was thrown - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -No exception was thrown - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -bar must be a negative number - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -No exception was thrown - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -bar must be a string - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -No exception was thrown - -Deprecated: The keyNested() rule is deprecated and will be removed in the next major version. Use nested key() or property() instead. %s -bar must be float diff --git a/tests/integration/transformers/deprecated_keyValue.phpt b/tests/integration/transformers/deprecated_keyValue.phpt deleted file mode 100644 index 7b4d9f381..000000000 --- a/tests/integration/transformers/deprecated_keyValue.phpt +++ /dev/null @@ -1,47 +0,0 @@ ---FILE-- - v::keyValue('foo', 'equals', 'bar')->assert(['bar' => 42])); -exceptionMessage(static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 42])); -exceptionMessage(static fn() => v::keyValue('foo', 'json', 'bar')->assert(['foo' => 42, 'bar' => 43])); -exceptionMessage(static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 1, 'bar' => 2])); -exceptionMessage(static fn() => v::not(v::keyValue('foo', 'equals', 'bar'))->assert(['foo' => 1, 'bar' => 1])); -exceptionFullMessage(static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['bar' => 42])); -exceptionFullMessage(static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 42])); -exceptionFullMessage(static fn() => v::keyValue('foo', 'json', 'bar')->assert(['foo' => 42, 'bar' => 43])); -exceptionFullMessage(static fn() => v::keyValue('foo', 'equals', 'bar')->assert(['foo' => 1, 'bar' => 2])); -exceptionFullMessage(static fn() => v::not(v::keyValue('foo', 'equals', 'bar'))->assert(['foo' => 1, 'bar' => 1])); -?> ---EXPECTF-- - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -foo must be present - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -bar must be present - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -bar must be valid to validate foo - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -foo must be equal to 2 - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -foo must not be equal to 1 - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -- foo must be present - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -- bar must be present - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -- bar must be valid to validate foo - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -- foo must be equal to 2 - -Deprecated: The keyValue() rule has been deprecated and will be removed in the next major version. Use nested lazy() instead. %s -- foo must not be equal to 1 diff --git a/tests/integration/transformers/deprecated_length.phpt b/tests/integration/transformers/deprecated_length.phpt deleted file mode 100644 index de9d82cd1..000000000 --- a/tests/integration/transformers/deprecated_length.phpt +++ /dev/null @@ -1,103 +0,0 @@ ---FILE-- - v::length(0, 5, false)->assert('forest')); -exceptionMessage(static fn() => v::length(10, 20)->assert('river')); -exceptionMessage(static fn() => v::length(15, null, false)->assert('mountain')); -exceptionMessage(static fn() => v::length(20)->assert('ocean')); -exceptionMessage(static fn() => v::length(2, 5)->assert('desert')); -exceptionMessage(static fn() => v::not(v::length(0, 15))->assert('rainforest')); -exceptionMessage(static fn() => v::not(v::length(0, 20, false))->assert('glacier')); -exceptionMessage(static fn() => v::not(v::length(3, null))->assert('meadow')); -exceptionMessage(static fn() => v::not(v::length(5, null, false))->assert('volcano')); -exceptionMessage(static fn() => v::not(v::length(5, 20))->assert('canyon')); -exceptionFullMessage(static fn() => v::length(0, 5, false)->assert('prairie')); -exceptionFullMessage(static fn() => v::length(0, 5)->assert('wetland')); -exceptionFullMessage(static fn() => v::length(15, null, false)->assert('tundra')); -exceptionFullMessage(static fn() => v::length(20)->assert('savanna')); -exceptionFullMessage(static fn() => v::length(7, 10)->assert('marsh')); -exceptionFullMessage(static fn() => v::length(4, 10, false)->assert('reef')); -exceptionFullMessage(static fn() => v::not(v::length(0, 15))->assert('valley')); -exceptionFullMessage(static fn() => v::not(v::length(0, 20, false))->assert('island')); -exceptionFullMessage(static fn() => v::not(v::length(5, null))->assert('plateau')); -exceptionFullMessage(static fn() => v::not(v::length(3, null, false))->assert('fjord')); -exceptionFullMessage(static fn() => v::not(v::length(5, 20))->assert('delta')); -exceptionFullMessage(static fn() => v::not(v::length(5, 11, false))->assert('waterfall')); -exceptionFullMessage(static fn() => v::length(8, 8)->assert('estuary')); -exceptionFullMessage(static fn() => v::not(v::length(5, 5))->assert('grove')); -?> ---EXPECTF-- - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(5) instead. %s -The length of "forest" must be less than 5 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(10, 20) instead. %s -The length of "river" must be between 10 and 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(15) instead. %s -The length of "mountain" must be greater than 15 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(20) instead. %s -The length of "ocean" must be greater than or equal to 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(2, 5) instead. %s -The length of "desert" must be between 2 and 5 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThanOrEqual(15) instead. %s -The length of "rainforest" must be greater than 15 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(20) instead. %s -The length of "glacier" must not be less than 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(3) instead. %s -The length of "meadow" must be less than 3 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(5) instead. %s -The length of "volcano" must not be greater than 5 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(5, 20) instead. %s -The length of "canyon" must not be between 5 and 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(5) instead. %s -- The length of "prairie" must be less than 5 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThanOrEqual(5) instead. %s -- The length of "wetland" must be less than or equal to 5 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(15) instead. %s -- The length of "tundra" must be greater than 15 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(20) instead. %s -- The length of "savanna" must be greater than or equal to 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(7, 10) instead. %s -- The length of "marsh" must be between 7 and 10 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetweenExclusive(4, 10) instead. %s -- The length of "reef" must be greater than 4 and less than 10 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThanOrEqual(15) instead. %s -- The length of "valley" must be greater than 15 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthLessThan(20) instead. %s -- The length of "island" must not be less than 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThanOrEqual(5) instead. %s -- The length of "plateau" must be less than 5 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthGreaterThan(3) instead. %s -- The length of "fjord" must not be greater than 3 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetween(5, 20) instead. %s -- The length of "delta" must not be between 5 and 20 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthBetweenExclusive(5, 11) instead. %s -- The length of "waterfall" must not be greater than 5 or less than 11 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthEquals(8) instead. %s -- The length of "estuary" must be equal to 8 - -Deprecated: Calling length() with scalar values has been deprecated, and will not be allowed in the next major version. Use lengthEquals(5) instead. %s -- The length of "grove" must not be equal to 5 diff --git a/tests/integration/transformers/deprecated_max.phpt b/tests/integration/transformers/deprecated_max.phpt deleted file mode 100644 index 26cc6afdf..000000000 --- a/tests/integration/transformers/deprecated_max.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::max(10)->assert(11)); -exceptionMessage(static fn() => v::not(v::max(10))->assert(5)); -exceptionFullMessage(static fn() => v::max('today')->assert('tomorrow')); -exceptionFullMessage(static fn() => v::not(v::max('b'))->assert('a')); -?> ---EXPECTF-- - -Deprecated: Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead. %s -11 must be less than or equal to 10 - -Deprecated: Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead. %s -5 must be greater than 10 - -Deprecated: Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead. %s -- "tomorrow" must be less than or equal to "today" - -Deprecated: Calling max() with a scalar value has been deprecated, and will be not allows in the next major version. Use lessThanOrEqual() instead. %s -- "a" must be greater than "b" diff --git a/tests/integration/transformers/deprecated_min.phpt b/tests/integration/transformers/deprecated_min.phpt deleted file mode 100644 index 06863e0b6..000000000 --- a/tests/integration/transformers/deprecated_min.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---FILE-- - v::min(INF)->assert(10)); -exceptionMessage(static fn() => v::not(v::min(5))->assert(INF)); -exceptionFullMessage(static fn() => v::min('today')->assert('yesterday')); -exceptionFullMessage(static fn() => v::not(v::min('a'))->assert('z')); -?> ---EXPECTF-- - -Deprecated: Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead. %s -10 must be greater than or equal to `INF` - -Deprecated: Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead. %s -`INF` must be less than 5 - -Deprecated: Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead. %s -- "yesterday" must be greater than or equal to "today" - -Deprecated: Calling min() with a scalar value has been deprecated, and will be not allows in the next major version. Use greaterThanOrEqual() instead. %s -- "z" must be less than "a" diff --git a/tests/integration/transformers/deprecated_type.phpt b/tests/integration/transformers/deprecated_type.phpt deleted file mode 100644 index ab2dffe9b..000000000 --- a/tests/integration/transformers/deprecated_type.phpt +++ /dev/null @@ -1,55 +0,0 @@ ---FILE-- - v::type('array')->assert(1)); -exceptionMessage(static fn() => v::type('bool')->assert(1)); -exceptionMessage(static fn() => v::type('boolean')->assert(1)); -exceptionMessage(static fn() => v::type('callable')->assert(1)); -exceptionMessage(static fn() => v::type('double')->assert(1)); -exceptionMessage(static fn() => v::type('float')->assert(1)); -exceptionMessage(static fn() => v::type('int')->assert('1')); -exceptionMessage(static fn() => v::type('integer')->assert('1')); -exceptionMessage(static fn() => v::type('null')->assert(1)); -exceptionMessage(static fn() => v::type('object')->assert(1)); -exceptionMessage(static fn() => v::type('resource')->assert(1)); -exceptionMessage(static fn() => v::type('string')->assert(1)); -?> ---EXPECTF-- - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use arrayType() instead. %s -1 must be an array - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use boolType() instead. %s -1 must be a boolean - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use boolType() instead. %s -1 must be a boolean - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use callableType() instead. %s -1 must be a callable - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use floatType() instead. %s -1 must be float - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use floatType() instead. %s -1 must be float - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use intType() instead. %s -"1" must be an integer - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use intType() instead. %s -"1" must be an integer - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use nullType() instead. %s -1 must be null - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use objectType() instead. %s -1 must be an object - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use resourceType() instead. %s -1 must be a resource - -Deprecated: The type() rule is deprecated and will be removed in the next major version. Use stringType() instead. %s -1 must be a string diff --git a/tests/integration/transformers/prefix.phpt b/tests/integration/transformers/prefix.phpt deleted file mode 100644 index 746b963a3..000000000 --- a/tests/integration/transformers/prefix.phpt +++ /dev/null @@ -1,80 +0,0 @@ ---FILE-- - [v::keyEquals('foo', 12), ['foo' => 10]], - 'length' => [v::lengthGreaterThan(3), 'foo'], - 'max' => [v::maxOdd(), [1, 2, 3, 4]], - 'min' => [v::minEven(), [1, 2, 3]], - 'not' => [v::notBetween(1, 3), 2], - 'nullOr' => [v::nullOrBoolType(), 'string'], - 'property' => [v::propertyBetween('foo', 1, 3), (object) ['foo' => 5]], - 'undefOr' => [v::undefOrUrl(), 'string'], -]); -?> ---EXPECT-- -key -⎺⎺⎺ -foo must be equal to 12 -- foo must be equal to 12 -[ - 'foo' => 'foo must be equal to 12', -] - -length -⎺⎺⎺⎺⎺⎺ -The length of "foo" must be greater than 3 -- The length of "foo" must be greater than 3 -[ - 'lengthGreaterThan' => 'The length of "foo" must be greater than 3', -] - -max -⎺⎺⎺ -As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number -- As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number -[ - 'maxOdd' => 'As the maximum of `[1, 2, 3, 4]`, 4 must be an odd number', -] - -min -⎺⎺⎺ -As the minimum from `[1, 2, 3]`, 1 must be an even number -- As the minimum from `[1, 2, 3]`, 1 must be an even number -[ - 'minEven' => 'As the minimum from `[1, 2, 3]`, 1 must be an even number', -] - -not -⎺⎺⎺ -2 must not be between 1 and 3 -- 2 must not be between 1 and 3 -[ - 'notBetween' => '2 must not be between 1 and 3', -] - -nullOr -⎺⎺⎺⎺⎺⎺ -"string" must be a boolean or must be null -- "string" must be a boolean or must be null -[ - 'nullOrBoolType' => '"string" must be a boolean or must be null', -] - -property -⎺⎺⎺⎺⎺⎺⎺⎺ -foo must be between 1 and 3 -- foo must be between 1 and 3 -[ - 'foo' => 'foo must be between 1 and 3', -] - -undefOr -⎺⎺⎺⎺⎺⎺⎺ -"string" must be a URL or must be undefined -- "string" must be a URL or must be undefined -[ - 'undefOrUrl' => '"string" must be a URL or must be undefined', -]