Commit graph

10 commits

Author SHA1 Message Date
Henrique Moody
b701fac656
Create ShortCircuit validator and ShortCircuitable interface
This commit introduces a mechanism for validators to return early once
the validation outcome is determined, rather than evaluating all child
validators.

The ShortCircuit validator evaluates validators sequentially and stops
at the first failure, similar to how PHP's && operator works. This is
useful when later validators depend on earlier ones passing, or when
you want only the first error message.

The ShortCircuitCapable interface allows composite validators (AllOf,
AnyOf, OneOf, NoneOf, Each, All) to implement their own short-circuit
logic.

Why "ShortCircuit" instead of "FailFast":

The name "FailFast" was initially considered but proved misleading.
While AllOf stops on failure (fail fast), AnyOf stops on success
(succeed fast), and OneOf stops on the second success. The common
behavior is not about failing quickly, but about returning as soon as
the outcome is determined—which is exactly what short-circuit
evaluation means. This terminology is familiar to developers from
boolean operators (&& and ||), making the behavior immediately
understandable.

Co-authored-by: Alexandre Gomes Gaigalas <alganet@gmail.com>
Assisted-by: Claude Code (Opus 4.5)
2026-02-05 17:32:42 +01:00
Henrique Moody
7c681fec66
Fix SPDX headers in all files
I ran the `bin/console spdx --fix` with different strategies for
different files. For most of the core classes, since they've been
drastically rebuilt, I've run it with the `git-blame` strategy, for for
the `src/Validators`, in which the API changed completely but the logic
remains the same, I use the `git-log` strategy.
2026-02-03 15:23:23 +01:00
Alexandre Gomes Gaigalas
53b3bded7d Improve performance of Prefix transformer
The Prefix transformer had many loops that could be avoided. This
change replaces them for a compiled PCRE regex, taking advantage
of recent PCRE JIT capabilities introduced in PHP.

These changes offer no performance trade-offs, improving lookup
for all categories of prefixes (property/key with shift, ignore
list and fallback to simple rule).

The most affected is the simple rule (no prefix or no conflict
with any kind of prefix rule), yielding the most gains.
2026-02-01 22:45:51 +00:00
Alexandre Gomes Gaigalas
47f8f82d7f Remove mathematical, niche and deprecated validators
This commit removes validators described in #1642, refactoring
to clean up after their removal.

 - Url was refactored to use the function `filter_var` instead.
 - tests/bootstrap.php is no longer needed and was removed.
 - Updated migration guide with recommendations for replacements.
2026-01-30 16:08:27 +00:00
Alexandre Gomes Gaigalas
d8e31dbc3a Containerize sokil databases
The main focus of this change is to make those optional dependencies
more testable.

Unfortunately, some phpstan-ignores had to be included, since ::set
is not a PsrContainer method. We're only using it on tests though,
so it's fine. It targets our php-di container for testing purposes
only. The real implementation only relies on ::get.

This change also has the side effect of improving the performance
of those validators by not instantiating their databases each time
a iso validator is built, achieving massive improvements in those
scenarios. A small benchmark with no assertions was added to track
that improvement.
2026-01-29 19:29:51 +00:00
Alexandre Gomes Gaigalas
9862963d06 Setup Continuous Performance
A new workflow, continuous-integration-perf.yml was introduced. It:

 - Checks out the `benchmarks` branch locally.
 - Runs the benchmarks, accounting for non-existant baselines
   and target (main/PR).
 - Stores the .phpbench storage folder and a human-readable
   report in the `benchmarks` branch.
 - Does not make a PR fail, and never reports a failure
   when merging to main.
 - Allows workflow_dispatch for quick re-runs, and has an
   option to reset the baseline in case something changes
   (GitHub runner setup gets faster/slower, major refactors,
   etc).

Thus, it keeps a historical record of all benchmark results.

These results can be viewed by exploring GitHub via the web
interface and seeing the changes in `latest.md` (the human
file commited).

Additionally, one can clone the `benchmarks` branch and run
`phpbench log` to explore the history in more detail.

Some adjustments to previously added benchmarks were made:

 - Assertions were included in order to track time and memory
   tresholds.
 - The benchmarks are now more surgical, and address the
   concrete validators instead of the whole chain validate.

These changes were made to make benchmarks more isolated, with
the intention of adding chain-related benchmarks separately
in the future.
2026-01-21 06:31:37 +00:00
Alexandre Gomes Gaigalas
d9cdc118b2 Introduce REUSE compliance
This commit introduces REUSE compliance by annotating all files
with SPDX information and placing the reused licences in the
LICENSES folder.

We additionally removed the docheader tool which is made obsolete
by this change.

The main LICENSE and copyright text of the project is now not under
my personal name anymore, and it belongs to "The Respect Project
Contributors" instead.

This change restores author names to several files, giving the
appropriate attribution for contributions.
2026-01-21 06:28:11 +00:00
Alexandre Gomes Gaigalas
0090191aaa Introduce tests for serialization of validators
This commit introduces a new feature test: SerializableTest, that
tests several validators for their ability to be serialized and
unserialized.

It also makes it so that the same list of validators can be used
by both simple benchmarks and "smoke tests" of all kinds, including
this serialize/unserialize one.

Additionally, the FilterVar validator was modified. Previously, due
to the use of Callback, it was not serializable, but now it is.
2026-01-19 09:24:38 +00:00
Alexandre Gomes Gaigalas
8e5938a059 Introduce ContainsCount validator
This validator is similar to Contains, but also checks how many
times the needle appears.

Additionally, the Domain validator was changed to use it instead
of relying on an unserializable callback, thus, making it
serializable.
2026-01-15 13:39:46 +00:00
Alexandre Gomes Gaigalas
abdc73bd56 Introduce phpbench benchmarks and profiles
This commit is the first step in setting up *Continuous Performance*
for the repository.

 - Adds phpbench/phpbench to dev dependencies.
 - Adds an initial `ValidatorBench.php` file with validate benchmarks
   for several validators.
 - Adds `composer bench` script to run benchmarks.
 - Adds `composer bench:profile` script to generate profiles.
2026-01-12 23:44:38 +00:00