Skip to content

Commit 86f889a

Browse files
committed
feat(application): Enhance PropertyInspector demo with diverse scenarios
- Add multiple test scenarios to demonstrate PropertyInspector functionality - Implement custom attributes (Validate, Sanitize) for property validation - Create User entity with decorated properties for testing - Develop CustomAttributeHandler for attribute processing - Introduce error handling and display for various validation cases - Standardize user names to "Walmir Silva" for consistency - Improve code organization with separate functions for processing and display
1 parent 71cf771 commit 86f889a

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

tests/application.php

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,181 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
require_once __DIR__ . '/../vendor/autoload.php';
6+
7+
use KaririCode\PropertyInspector\AttributeAnalyzer;
8+
use KaririCode\PropertyInspector\Contract\PropertyAttributeHandler;
9+
use KaririCode\PropertyInspector\Exception\PropertyInspectionException;
10+
use KaririCode\PropertyInspector\PropertyInspector;
11+
12+
// Custom Attributes
13+
#[Attribute(Attribute::TARGET_PROPERTY)]
14+
final class Validate
15+
{
16+
public function __construct(public readonly array $rules)
17+
{
18+
}
19+
}
20+
21+
#[Attribute(Attribute::TARGET_PROPERTY)]
22+
final class Sanitize
23+
{
24+
public function __construct(public readonly string $method)
25+
{
26+
}
27+
}
28+
29+
// Sample Entity
30+
final class User
31+
{
32+
public function __construct(
33+
#[Validate(['required', 'string', 'min:3'])]
34+
#[Sanitize('trim')]
35+
public string $name,
36+
#[Validate(['required', 'email'])]
37+
#[Sanitize('lowercase')]
38+
public string $email,
39+
#[Validate(['required', 'integer', 'min:18'])]
40+
public int $age
41+
) {
42+
}
43+
}
44+
45+
// Custom Attribute Handler
46+
final class CustomAttributeHandler implements PropertyAttributeHandler
47+
{
48+
public function handleAttribute(object $object, string $propertyName, object $attribute, mixed $value): ?string
49+
{
50+
return match (true) {
51+
$attribute instanceof Validate => $this->validate($propertyName, $value, $attribute->rules),
52+
$attribute instanceof Sanitize => $this->sanitize($propertyName, $value, $attribute->method),
53+
default => null,
54+
};
55+
}
56+
57+
private function validate(string $propertyName, mixed $value, array $rules): ?string
58+
{
59+
$errors = array_filter(array_map(
60+
fn ($rule) => $this->applyValidationRule($propertyName, $value, $rule),
61+
$rules
62+
));
63+
64+
return empty($errors) ? null : implode(' ', $errors);
65+
}
66+
67+
private function applyValidationRule(string $propertyName, mixed $value, string $rule): ?string
68+
{
69+
return match (true) {
70+
'required' === $rule && empty($value) => "$propertyName is required.",
71+
'string' === $rule && !is_string($value) => "$propertyName must be a string.",
72+
str_starts_with($rule, 'min:') => $this->validateMinRule($propertyName, $value, $rule),
73+
'email' === $rule && !filter_var($value, FILTER_VALIDATE_EMAIL) => "$propertyName must be a valid email address.",
74+
'integer' === $rule && !is_int($value) => "$propertyName must be an integer.",
75+
default => null,
76+
};
77+
}
78+
79+
private function validateMinRule(string $propertyName, mixed $value, string $rule): ?string
80+
{
81+
$minValue = (int) substr($rule, 4);
82+
83+
return match (true) {
84+
is_string($value) && strlen($value) < $minValue => "$propertyName must be at least $minValue characters long.",
85+
is_int($value) && $value < $minValue => "$propertyName must be at least $minValue.",
86+
default => null,
87+
};
88+
}
89+
90+
private function sanitize(string $propertyName, mixed $value, string $method): string
91+
{
92+
return match ($method) {
93+
'trim' => trim($value),
94+
'lowercase' => strtolower($value),
95+
default => (string) $value,
96+
};
97+
}
98+
}
99+
100+
function runApplication(): void
101+
{
102+
$attributeAnalyzer = new AttributeAnalyzer(Validate::class);
103+
$propertyInspector = new PropertyInspector($attributeAnalyzer);
104+
$handler = new CustomAttributeHandler();
105+
106+
// Scenario 1: Valid User
107+
$validUser = new User(' WaLmir Silva ', 'WALMIR.SILVA@EXAMPLE.COM', 25);
108+
processUser($propertyInspector, $handler, $validUser, 'Scenario 1: Valid User');
109+
110+
// Scenario 2: Invalid User (Age below 18)
111+
$underageUser = new User('Walmir Silva', 'walmir@example.com', 16);
112+
processUser($propertyInspector, $handler, $underageUser, 'Scenario 2: Underage User');
113+
114+
// Scenario 3: Invalid User (Empty name and invalid email)
115+
$invalidUser = new User('', 'invalid-email', 30);
116+
processUser($propertyInspector, $handler, $invalidUser, 'Scenario 3: Invalid User Data');
117+
118+
// Scenario 4: Non-existent Attribute (to trigger an exception)
119+
try {
120+
$invalidAttributeAnalyzer = new AttributeAnalyzer('NonExistentAttribute');
121+
$invalidPropertyInspector = new PropertyInspector($invalidAttributeAnalyzer);
122+
$invalidPropertyInspector->inspect($validUser, $handler);
123+
} catch (PropertyInspectionException $e) {
124+
echo "\nScenario 4: Non-existent Attribute\n";
125+
echo 'Error: ' . $e->getMessage() . "\n";
126+
}
127+
}
128+
129+
function processUser(PropertyInspector $inspector, PropertyAttributeHandler $handler, User $user, string $scenario): void
130+
{
131+
echo "\n$scenario\n";
132+
echo 'Original User: ' . json_encode($user) . "\n";
133+
134+
try {
135+
$results = $inspector->inspect($user, $handler);
136+
displayResults($results);
137+
138+
if (empty($results)) {
139+
sanitizeUser($user);
140+
displaySanitizedUser($user);
141+
} else {
142+
echo "Validation failed. User was not sanitized.\n";
143+
}
144+
} catch (PropertyInspectionException $e) {
145+
echo "An error occurred during property inspection: {$e->getMessage()}\n";
146+
}
147+
}
148+
149+
function displayResults(array $results): void
150+
{
151+
if (empty($results)) {
152+
echo "All properties are valid.\n";
153+
154+
return;
155+
}
156+
157+
echo "Validation Results:\n";
158+
foreach ($results as $propertyName => $propertyResults) {
159+
echo "Property: $propertyName\n";
160+
foreach ($propertyResults as $result) {
161+
if (null !== $result) {
162+
echo " - $result\n";
163+
}
164+
}
165+
}
166+
}
167+
168+
function sanitizeUser(User $user): void
169+
{
170+
$user->name = trim($user->name);
171+
$user->email = strtolower($user->email);
172+
}
173+
174+
function displaySanitizedUser(User $user): void
175+
{
176+
echo "Sanitized User:\n";
177+
echo json_encode($user) . "\n";
178+
}
179+
180+
// Run the application
181+
runApplication();

0 commit comments

Comments
 (0)