Feature: Assertions
Problem Statement
Hazaar currently lacks a centralized and robust mechanism for performing assertions and input guarding, which makes it cumbersome for developers to validate inputs consistently. A modern assertion system with both fluent and lazy evaluation would allow for expressive and efficient input validation. Lazy assertions, in particular, would enable multiple validations to be accumulated and reported as a single batch, improving debugging and error reporting.
Who will benefit?
- Developers building applications with Hazaar who require expressive and batch-capable validation mechanisms.
- Teams aiming to enhance code readability while improving error handling and reporting for invalid inputs.
- Applications requiring strict validation for multiple inputs without interrupting execution on the first failure.
Benefits and risks
Benefits
- Provides a unified and expressive API for both immediate and lazy input validation.
- Improves code readability and maintainability with a fluent, chainable interface.
- Facilitates efficient debugging by reporting all validation failures at once with lazy assertions.
- Reduces repetitive validation boilerplate.
Risks
- Misuse of the API (e.g., overly complex lazy validation chains) could make debugging harder for certain edge cases.
- Requires careful design to ensure clear and concise error messages for lazy validation failures.
Proposed solution
Enhance the Assert
class in Hazaar to support both fluent assertions and lazy assertions. The solution should:
- Use a builder-style API for fluent assertions.
- Introduce a
lazy()
mode that collects validation results and reports them in a single batch. - Throw meaningful exceptions (e.g.,
InvalidArgumentException
) for immediate assertions and aggregated errors (e.g.,ValidationException
) for lazy assertions. - Provide methods for common validations (e.g., type checking, value ranges, string length, patterns, etc.) and support extensibility for custom rules.
Example API
Fluent Assertions
use Hazaar\Validation\Assert;
Assert::that($value)
->notEmpty('Value cannot be empty.')
->string('Value must be a string.')
->matchesRegex('/^[a-z]+$/', 'Value must only contain lowercase letters.');
Lazy Assertions
use Hazaar\Validation\Assert;
Assert::lazy()
->that($value1, 'Value1')
->string('Must be a string.')
->notEmpty('Cannot be empty.')
->that($value2, 'Value2')
->integer('Must be an integer.')
->max(42, 'Must not exceed 42.')
->verify(); // Throws a ValidationException with all failures.
Integration
- Use fluent assertions for immediate input validation in critical areas.
- Use lazy assertions for bulk validation where multiple inputs need to be validated and reported together.
- Extend the framework to integrate the Assert class into request handling, routing, and other validation-heavy processes.
Examples
- Validating user input in a controller:
use Hazaar\Validation\Assert;
public function processInput(array $data) {
Assert::lazy()
->that($data['username'], 'Username')
->notEmpty('Username is required.')
->string('Username must be a string.')
->that($data['email'], 'Email')
->notEmpty('Email is required.')
->email('Invalid email address.')
->verify(); // Collect and report all errors.
// Proceed with processing...
}
- Validating multiple configuration parameters:
Assert::lazy()
->that($config['debug'], 'Debug')
->boolean('Debug must be a boolean.')
->that($config['cache_ttl'], 'Cache TTL')
->integer('Cache TTL must be an integer.')
->min(0, 'Cache TTL cannot be negative.')
->verify();
Priority/Severity
-
High (This will bring a huge increase in performance/productivity/usability/legislative cover) -
Medium (This will bring a good increase in performance/productivity/usability) -
Low (anything else e.g., trivial, minor improvements)
Edited by Jamie Carl