Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1654 +/- ##
=========================================
Coverage 99.29% 99.30%
- Complexity 920 924 +4
=========================================
Files 190 191 +1
Lines 2141 2151 +10
=========================================
+ Hits 2126 2136 +10
Misses 15 15 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
8c70dee to
2c5b8db
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a new Patterned validator that formats input values using patterns in error messages while still validating the original unformatted input. This complements the existing Masked validator by adding formatting instead of hiding sensitive data.
Changes:
- Adds
Patternedvalidator that applies pattern-based formatting to input values in error messages - Integrates the new validator into all mixin interfaces (Chain, Builder, and their variants)
- Provides comprehensive test coverage including unit tests, feature tests, and smoke tests
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Validators/Patterned.php | Implements the core Patterned validator using PatternFormatter from respect/string-formatter |
| tests/unit/Validators/PatternedTest.php | Unit tests covering invalid patterns, non-string inputs, and formatting behavior |
| tests/feature/Validators/PatternedTest.php | Feature tests for error message formatting with real validators (CPF) |
| tests/src/SmokeTestProvider.php | Adds smoke test case demonstrating uppercase transformation |
| src/Mixins/*.php | Updates all 12 mixin interfaces to include patterned() methods |
| docs/validators/Patterned.md | Comprehensive documentation with examples, behavior description, and categorization |
| docs/validators.md | Adds Patterned to Display and Miscellaneous categories and alphabetical list |
| docs/migrating-from-v2-to-v3.md | Documents Patterned as a new v3.0 validator with examples |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
2c5b8db to
9e2cb85
Compare
docs/migrating-from-v2-to-v3.md
Outdated
| v::patterned('0{3}.0{3}.0{3}-0{2}', v::cpf())->assert('12345678900'); | ||
| // → "123.456.789-00" must be a valid CPF number | ||
|
|
||
| v::patterned('(0{2}) 0{5}-0{4}', v::phone())->assert('11987654321'); | ||
| // → "(11) 98765-4321" must be a valid telephone number |
There was a problem hiding this comment.
I was wondering if we could also document some common number patterns:
Thousands separation: 1000000 -> 1.000.000
Comma separation: 10.00 => 10,00
I think those are by far the most popular use cases for adding patterns to some display value.
The Patterned validator formats input values using a pattern before
displaying them in error messages, while still validating the original
unformatted input. This is the complement to the Masked validator:
- Masked: Hides sensitive parts of the input (e.g., "4111****1111")
- Patterned: Adds formatting to raw input (e.g., "4111 1111 1111 1111")
This validator solves a common UX problem: when users submit data without
formatting characters (like spaces or punctuation), error messages show
the raw input, which can be harder to read and verify. For example:
- Credit card "4111111111111112" → "4111 1111 1111 1112"
- CPF "12345678900" → "123.456.789-00"
- Phone "11987654321" → "(11) 98765-4321"
The validator is particularly useful in scenarios where:
1. Form inputs strip formatting characters before submission
2. Data comes from external systems without formatting
3. Users need to visually verify the value they entered
4. Error messages should match the expected display format
It uses the PatternFormatter from respect/string-formatter, which supports
digit placeholders (0), quantifiers ({n}), and transformations (\u for
uppercase, \l for lowercase, etc.).
Assisted-by: Claude Code (Opus 4.5)
9e2cb85 to
cd34498
Compare
| * SPDX-FileContributor: Henrique Moody <henriquemoody@gmail.com> | ||
| */ | ||
|
|
||
| declare(strict_types=1); |
| v::patterned('$00.00', v::phone())->assert(1297); | ||
| // → "$12.97" must be a valid telephone number |
There was a problem hiding this comment.
This example is misleading. The use of $ implies a monterary value, but the validator used is a phone number.
Suggestion: Keep the phone number, and instead add examples for the most popular use cases:
- Thousands separator
- Decimals separator
- Dates
|
Noted the comments, but I will close this one in favor of #1657 with some aliases. I will implemente your comments there. |
The Patterned validator formats input values using a pattern before displaying them in error messages, while still validating the original unformatted input. This is the complement to the Masked validator:
This validator solves a common UX problem: when users submit data without formatting characters (like spaces or punctuation), error messages show the raw input, which can be harder to read and verify. For example:
The validator is particularly useful in scenarios where:
It uses the PatternFormatter from respect/string-formatter, which supports digit placeholders (0), quantifiers ({n}), and transformations (\u for uppercase, \l for lowercase, etc.).
Assisted-by: Claude Code (Opus 4.5)