Commit graph

2127 commits

Author SHA1 Message Date
Henrique Moody 4fd26e39bb
Rename "NotOptional" to "NotUndef"
Since I've already renamed the "Optional" rule to "UnderOf," it makes
sense to rename this rule too.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-05-06 20:45:27 +02:00
Danilo Correa 719f12a424
Increase code coverage of some rules
We were not thoroughly testing quite a few rules, especially the
constructor of some of them.

This commit increases the code coverage, ensuring almost every single
line in the "Rules" namespace is covered.
2024-04-23 16:01:55 +02:00
Henrique Moody 2ae1df177a
Allow to customise messages while asserting
Because we now have a single "assert()" method, we have more freedom to
add more customizations to it. This specific one is handy if someone
wants to use the library to validate but wants to use their own
exceptions.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-26 15:04:04 +01:00
Henrique Moody d7dc0f2b4e
Refactor the "NullOr" rule and related classes
This commit will rename the "Nullable" rule to "NullOr" while soft
deprecating the old name. It should work the same as the previous one
but with a different name. It will also prefix the result ID, allowing
more message customization.

While working on it, I realized that the prefix "nullOr" had a typo,
and it was using "nullOf" instead. I fixed that, too.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-26 01:55:50 +01:00
Henrique Moody 707dcae65f
Refactor the "UndefOr" rule and related classes
This commit will rename the "Optional" rule to"UndefOr" while soft
deprecating the old name. It should work the same as the previous one
but with a different name. It will also prefix the result ID, allowing
more message customization.

While working on it, I realized that the prefix "undefOr" had a typo,
and it was using "undefOf" instead. I fixed that, too.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-26 01:35:36 +01:00
Henrique Moody eeaea466ac
Prefix IDs of wrapper rule results
Because some rules work more as a prefix, it makes sense to prefix their
result ID. That will allow for a more intuitive templating, especially
when using those rules as prefixes.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-26 01:23:29 +01:00
Henrique Moody 8573bc5d45
Do not overwrite "IDs" when updating names
When you have a chain of rules in the Validation and overwrite the name
with "setName()," it's impossible to get the messages from all rules in
the chain as an array because they all have the same name.

These changes will change that behavior by creating a more explicit
distinction between "IDs" and "names." The "IDs" will remain
unchangeable, while we can always overwrite the names. That means that
the array messages will look more similar to the chain, and it will be
possible to overwrite the messages from multiple rules in the same
chain.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-26 01:12:44 +01:00
Henrique Moody 9322cd6375
Do not create results with siblings in the When rule
When creating a result with a sibling in the When rule, the result
generates an unhelpful message. In most of the use cases of the When
rule, the initial rule ("when") is only helpful in determining which
will be the "real" rule to use.

Those changes will change the When rule not to generate results with
siblings.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 23:47:25 +01:00
Henrique Moody fefe905e0b
Include "__root__" when getting message as an array
When converting an object into an array, we exclude the message root
message from it. Since we're using a convention to template those
messages as an array, we could also use the same convention to return
those messages.

While working on it, I noticed that the name "__self__" wasn't
reflecting what that really meant, so I renamed it "__root__" because it
better reflects the meaning of those messages/templates.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 22:38:19 +01:00
Henrique Moody d1f108dc87
Make proper use of exceptions in rules
This commit will ensure that all rules that cannot be created because of
invalid arguments in the constructor will throw the
InvalidRuleConstructorException. It will also make ComponentException
extend LogicException, which makes it easier to determine that the
client has improperly used the library.

I also introduced some tests for two exceptions with logic in their
constructor.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 22:09:02 +01:00
The Respect Panda ae7a20f6d3
Update Regional Information 2024-03-25 18:43:50 +01:00
Henrique Moody 66faefd695
Remove previous validation engine
After many refactorings, no rules use the previous validation engine.
That means we can remove the unused code from the repository and switch
from the previous to the new validation engine everywhere.

This commit will also soft deprecate the methods "validate()", and
"check()" in all the rules and the "assert()" in all rules but the
Validator itself. That means using those methods will still be allowed,
but static analysis tools might complain.

This is a big step toward releasing the next major version, as the code
is pretty much the way it should be when I release the next version.
There's some documentation to be updated, and I would like to change the
behavior of a couple of rules.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 12:28:25 +01:00
Henrique Moody ae369c4791
Improve Phone validation
This commit will improve the Phone rule in the following ways:

* Upgrade its validation engine;

* Increase the number of tests;

* Do not validate phone numbers from other regions.

The last item is a possible bug with "libphonenumber-for-php", which I
have already reported.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 08:48:31 +01:00
Henrique Moody 92b196ee19
Update the validation engine of the "Size" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 08:36:22 +01:00
Henrique Moody eb5f9a90e7
Update the validation engine of age-related rules
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 08:31:13 +01:00
Henrique Moody b653b055b4
Update the validation engine of the "Ip" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 00:15:43 +01:00
Henrique Moody dd3a87b2db
Update the validation engine of the "Sorted" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-25 00:13:32 +01:00
Henrique Moody 18923a2c93
Update the validation engine of the "VideoUrl" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 19:32:38 +01:00
Henrique Moody 74cb7bd509
Update the validation engine of the "CreditCard" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 18:16:25 +01:00
Henrique Moody 67888e1b8d
Update the validation engine of the "Uuid" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 18:11:34 +01:00
Henrique Moody ea605b61b6
Simplify InvalidRuleConstructorException
The message wasn't looking very user friendly, so I changed it a little
bit.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 18:06:38 +01:00
Henrique Moody 630e6ecb6d
Update the validation engine of the "NotEmpty" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 17:26:00 +01:00
Henrique Moody d116086f49
Update the validation engine of the "NotBlank" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 17:23:48 +01:00
Henrique Moody c198547a17
Update the validation engine of the "NotOptional" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 17:19:30 +01:00
Henrique Moody 8805c88d4c
Update the validation engine of the "DateTime" rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 17:16:25 +01:00
Henrique Moody 97b243daa1
Allow building rules using prefixes
Although helpful, the changes in the Min, Max, and Length rules made
using those rules more verbose. This commit will simplify their use by
allowing users to use them as prefixes.

Because I was creating prefixes for those rules, I made other cool
prefixes. Doing that is scary because it will generate more code to
support, and I would have liked to avoid that. However, that's a
valuable addition, and it's worth the risk.

I might reconsider that in the future, but for now, that looks like a
good idea.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-24 16:58:24 +01:00
Henrique Moody 9eafe52252
Refactor the Length rule
Currently, the Length rule does multiple things, yet it's limited.
Because it does many things, it's also confusing. Turning the Length
rule into a transformation allows for way more flexibility and clarity.

The syntax becomes more verbose, but I can solve that later by creating
a Transformer enables creating rules with the "length" as a prefix.

While making this change, I also removed the support for counting
objects and integers. I find that way too confusing.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-19 15:38:29 +01:00
Henrique Moody b2250c65a0
Improve how we handle data providers
We frequently repeat ourselves in the data providers. There's a clear
advantage to that, as it increases the number of possibilities with the
test, but it can also be annoying when we have to repeat ourselves.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-17 22:30:23 +01:00
dependabot[bot] 28b3f88627 Bump codecov/codecov-action from 3 to 4
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-15 11:43:46 +01:00
dependabot[bot] 81e67e277f Bump peter-evans/create-pull-request from 5 to 6
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5 to 6.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v6)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-15 11:42:50 +01:00
Ville Hukkamäki a5d042be7b
Create "Hetu" rule
This rule validates Finnish personal identity codes.

Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-15 11:28:08 +01:00
Henrique Moody 52b75bc1ed
Create BetweenExclusive rule
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-11 11:57:24 +01:00
Henrique Moody 1e2c1bfe30
Create transformers for deprecated rules
For now, those transformers will help transition from the current major
version to the next. As I'm making so many changes to the behaviour of
the rules and renaming others, it could be overwhelming to update all of
them suddenly.

The Transformers will change the rules' specifications before the
Factory creates them, allowing us to keep the behaviour of the old rules
-- even if a little bit different -- while triggering E_USER_DEPRECATED
errors to indicate that the client needs to update their code until the
next major version.

However, those transformers will do more shortly, for example, allowing
us to prefix rules to make it easier to create complex rules, like
`notPositive()` or even `keyBetween('foo', 1, 10)` and so on.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-08 22:03:43 +01:00
Henrique Moody fe68eab37d
Allow to validate ArrayObject in key-related values
Because of that, I also updated some data providers to distinguish
between "values" and "types", similar to some of the rules we already
have.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-08 21:36:49 +01:00
Henrique Moody 7ded68c550
Update validation enginer of a few rules
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-07 02:57:39 +01:00
Henrique Moody 8dab012d3f
Update URL of build status image
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-07 01:52:38 +01:00
Henrique Moody 235805a654
Fix some PHPStan issues
Unfortunately, we can't automatically run PHPStan in the PHPT files
because it will complain about the "strict_types" not being declared as
the first part of the file. I did some workaround that and fixed some
issues.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-07 01:48:45 +01:00
Henrique Moody fdd8c5a978
Remove unused code from the old validation engine
Because we've changed the validation engine, those classes are not
necessary anymore. This is a major step for the new validation engine.

The NestedValidationException was one of the most important classes of
the project, the one that formatted nested messages -- and it was also
one of the buggiest and most complicated ones. With the new validation
engine, it became obsolete.

These changes are a significant step toward refactoring the whole
codebase. The changes in the Factory are there to ensure it doesn't
break for the time being.

Thank you NestedValidationException; you did an excellent job for a long
time. I can't say I will miss you, but seeing you go is weird.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-07 00:59:45 +01:00
Henrique Moody 3a6a71a1f8
Update the validation engine of the "Domain" rule
I also decided to make the messages way more straightforward than
before. Instead of showing why the input is not a valid domain, we're
now simply saying that the input is not a proper domain.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-07 00:43:32 +01:00
Henrique Moody 2610a380dc
Replace "LazyConsecutive" with "Consecutive"
With this and the Lazy rule, the LazyConsecutive lost its purpose.

While working on it, I did refactor the Domain rule a bit, but mainly to
check how this rule could behave.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-06 23:57:49 +01:00
Henrique Moody 78715fb844
Create "Lazy" rule
This rule resembles a proper replacement for the old "KeyValue" rule
rather than the "LazyConsecutive" rule[1]. I will soon delete the
"LazyConsecutive" rule and replace it with something else.

[1]: 41245f663f

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-06 22:06:44 +01:00
Henrique Moody df16ddaf48
Improve composite-based rules
Because the rules' property is read-only, there aren't many reasons not
to expose that, especially since we already expose the rules anyways.

I also changed the implementation of "OneOf" because we don't see "xor"
enough these days.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-06 18:02:39 +01:00
Henrique Moody 24885e4a5f
Remove "KeyNested" rule
Because we have the Key and Property rules, the KeyNested is redundant,
although it's a helpful shortcut.

The real problem is dealing with messages and templates because the
structure of the validator needs to match the structure of the rule.
When using the `getMessages()` method from the exception we throw in
`assert()`, we get a flat structure, which is often not the intended
structure.

The KeyNested rule is cool, but it adds some complexity to the codebase
that I'm unwilling to deal with. It's not nice to remove a rule,
especially because I know people use it, but it's for the best. I'm
trying to keep the codebase small, so hopefully, it will get easier to
maintain.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-05 02:28:16 +01:00
Henrique Moody d36572cc25
Split the "Property" rule
Currently, the Property rule has a third parameter that allows the
validation of the wrapped rule to be optional, meaning that the
validation will only happen if the property exists. That parameter makes
the rule harder to understand at times.

I'm splitting the Property rule into Property, PropertyExists, and
PropertyOptional. That way, it becomes apparent when someone wants only
to validate whether a property exists or if they will validate the value
of the property only when it exists.

I deliberately didn't create an abstract class because those rules are
different enough not to have an abstraction. In fact, I can see myself
deleting the AbstractRelated after I refactor the KeyNested rule.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-05 00:48:31 +01:00
Henrique Moody a647a4737b
Split "Key" rules
Currently, the Key rule has a third parameter that allows the validation
of the wrapped rule to be optional, meaning that the validation will
only happen if the key exists. That parameter makes the rule harder to
understand at times.

I'm splitting the Key rule into Key, KeyExists, and KeyOptional. That
way, it becomes apparent when someone wants only to validate whether a
key exists or if they're going to validate the value of the key only
when it exists.

I deliberately didn't create an abstract class because those rules are
different enough not to have an abstraction. In fact, I can see myself
deleting the  "AbstractRelated" in the upcoming changes.

With these changes, the KeySet rule will not accept validating if the
key exists or validating the value only if the key exists. I should
refactor that soon, and I will likely need to create a common interface
for Key, KeyExists, and KeyOptional.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-04 00:06:18 +01:00
Henrique Moody c946f16f60
Move mixin classes to the "Mixin" namespace
Just to make the root directory cleaner.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-03 16:52:29 +01:00
Henrique Moody cea77d2a46
Recreate "Max" rule
The "Max" rule is not a transformation, validating the maximum value in
the input against a given rule.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-03 16:39:44 +01:00
Henrique Moody 81befe8fa1
Move core rules into the "Core" namespace
That helps organize the code better, making it easier to spot the core
rule. It also helps not allow the Factory to load those rules, as the
new namespace is not registered in it.

Note that the "AbstractAge", "AbstractRelated", and "AbstractRule" were
not moved. I want to do that only when I refactor them.

After I moved classes, I realized that "Comparison" and "FilteredString"
had no tests. I created the tests, and while I did that, I spotted two
bugs:

* The "Equals" rule was failing when comparing non-scalar wth scalar
  values;

* The "Equals" and "Identical" rules were not working correctly because
  "Comparison" was converting their values.

I fixed those bugs in this commit.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-03 16:12:58 +01:00
Henrique Moody 433ceb4452
Update the validation engine of the "Each" rule
These changes will also introduce an abstract rule that validates
non-empty-iterable values. The abstract rule can also be the parent of
the recently created "Min" rule. Therefore, I've changed that class too.

I've introduced many tests for the "Each" rule to make sure what its
expected behavior is. I'm not super happy with its output, but I tried a
couple of options, and it is the best choice.

Note that Each now rejects `stdClass` and empty iterable values. I
thought that would make sense, as it would be useless when the input is
empty.

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-03 14:45:47 +01:00
Henrique Moody 210aa4ac01
Recreate "IterableType" rule
The difference with this rule is that it matches the behavior of
`is_iterable()`, which is different from `IterableVal` that also allows
instances of `stdClass.`

This is a necessary change because PHP will trigger an error when trying
to pass any object to anything typed as `iterable`

Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
2024-03-02 13:20:13 +01:00