- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
187 lines
6.3 KiB
PHP
187 lines
6.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\LiveComponents\Exceptions\StateValidationException;
|
|
use App\Framework\LiveComponents\Validation\DefaultStateValidator;
|
|
use App\Framework\LiveComponents\Validation\DerivedSchema;
|
|
use App\Framework\LiveComponents\Validation\SchemaCache;
|
|
use App\Framework\LiveComponents\ValueObjects\ComponentData;
|
|
|
|
echo "=== State Validation Test ===\n\n";
|
|
|
|
// Setup
|
|
$validator = new DefaultStateValidator();
|
|
$schemaCache = new SchemaCache();
|
|
|
|
// Create a User class for testing
|
|
$userClass = new class () {
|
|
public string $name = 'John';
|
|
};
|
|
|
|
// Test 1: Schema Derivation from Data
|
|
echo "Test 1: Schema Derivation from Data\n";
|
|
echo "------------------------------------\n";
|
|
$data = ComponentData::fromArray([
|
|
'count' => 0,
|
|
'items' => ['a', 'b'],
|
|
'user' => $userClass,
|
|
'metadata' => null,
|
|
]);
|
|
|
|
$schema = $validator->deriveSchema($data);
|
|
echo "✓ Schema derived successfully\n";
|
|
echo " Fields: " . json_encode($schema->toArray()) . "\n";
|
|
echo " Field count: " . $schema->getFieldCount() . "\n";
|
|
|
|
// Test 2: Valid State Validation
|
|
echo "\nTest 2: Valid State Validation\n";
|
|
echo "-------------------------------\n";
|
|
$newData = ComponentData::fromArray([
|
|
'count' => 5,
|
|
'items' => ['c', 'd', 'e'],
|
|
'user' => $userClass, // Same user class instance
|
|
'metadata' => null,
|
|
]);
|
|
|
|
try {
|
|
$validator->validate($newData, $schema);
|
|
echo "✓ Valid state passed validation\n";
|
|
} catch (StateValidationException $e) {
|
|
echo "✗ Unexpected validation error: " . $e->getMessage() . "\n";
|
|
exit(1);
|
|
}
|
|
|
|
// Test 3: Type Mismatch Detection
|
|
echo "\nTest 3: Type Mismatch Detection\n";
|
|
echo "--------------------------------\n";
|
|
$invalidData = ComponentData::fromArray([
|
|
'count' => 'five', // String instead of int
|
|
'items' => ['a', 'b'],
|
|
'user' => $userClass,
|
|
'metadata' => null,
|
|
]);
|
|
|
|
try {
|
|
$validator->validate($invalidData, $schema);
|
|
echo "✗ Should have thrown StateValidationException!\n";
|
|
exit(1);
|
|
} catch (StateValidationException $e) {
|
|
echo "✓ Correctly detected type mismatch\n";
|
|
echo " Error: " . $e->getUserMessage() . "\n";
|
|
echo " Field: " . ($e->getField() ?? 'N/A') . "\n";
|
|
}
|
|
|
|
// Test 4: Missing Required Field
|
|
echo "\nTest 4: Missing Required Field\n";
|
|
echo "-------------------------------\n";
|
|
$incompleteData = ComponentData::fromArray([
|
|
'count' => 10,
|
|
// 'items' missing
|
|
'user' => $userClass,
|
|
'metadata' => null,
|
|
]);
|
|
|
|
try {
|
|
$validator->validate($incompleteData, $schema);
|
|
echo "✗ Should have thrown StateValidationException!\n";
|
|
exit(1);
|
|
} catch (StateValidationException $e) {
|
|
echo "✓ Correctly detected missing field\n";
|
|
echo " Error: " . $e->getUserMessage() . "\n";
|
|
echo " Field: " . ($e->getField() ?? 'N/A') . "\n";
|
|
}
|
|
|
|
// Test 5: Unexpected Field
|
|
echo "\nTest 5: Unexpected Field\n";
|
|
echo "------------------------\n";
|
|
$extraFieldData = ComponentData::fromArray([
|
|
'count' => 0,
|
|
'items' => ['a', 'b'],
|
|
'user' => $userClass,
|
|
'metadata' => null,
|
|
'extra_field' => 'unexpected', // Not in original schema
|
|
]);
|
|
|
|
try {
|
|
$validator->validate($extraFieldData, $schema);
|
|
echo "✗ Should have thrown StateValidationException!\n";
|
|
exit(1);
|
|
} catch (StateValidationException $e) {
|
|
echo "✓ Correctly detected unexpected field\n";
|
|
echo " Error: " . $e->getUserMessage() . "\n";
|
|
echo " Field: " . ($e->getField() ?? 'N/A') . "\n";
|
|
}
|
|
|
|
// Test 6: SchemaCache Functionality
|
|
echo "\nTest 6: SchemaCache Functionality\n";
|
|
echo "----------------------------------\n";
|
|
$componentClass = 'App\\Test\\TestComponent';
|
|
|
|
echo " Checking cache (should be empty): " . ($schemaCache->has($componentClass) ? 'cached' : 'not cached') . "\n";
|
|
|
|
$schemaCache->set($componentClass, $schema);
|
|
echo " After set: " . ($schemaCache->has($componentClass) ? 'cached' : 'not cached') . "\n";
|
|
|
|
$cachedSchema = $schemaCache->get($componentClass);
|
|
if ($cachedSchema !== null && $cachedSchema->toArray() === $schema->toArray()) {
|
|
echo "✓ SchemaCache correctly stores and retrieves schemas\n";
|
|
} else {
|
|
echo "✗ SchemaCache retrieval failed\n";
|
|
exit(1);
|
|
}
|
|
|
|
$stats = $schemaCache->getStats();
|
|
echo " Cache stats: " . $stats['cached_count'] . " schema(s) cached\n";
|
|
|
|
$schemaCache->clear($componentClass);
|
|
echo " After clear: " . ($schemaCache->has($componentClass) ? 'cached' : 'not cached') . "\n";
|
|
|
|
// Test 7: DerivedSchema Helper Methods
|
|
echo "\nTest 7: DerivedSchema Helper Methods\n";
|
|
echo "-------------------------------------\n";
|
|
echo " Has 'count' field: " . ($schema->hasField('count') ? 'yes' : 'no') . "\n";
|
|
echo " Has 'nonexistent' field: " . ($schema->hasField('nonexistent') ? 'yes' : 'no') . "\n";
|
|
echo " Type of 'count': " . ($schema->getType('count') ?? 'N/A') . "\n";
|
|
echo " Is 'metadata' nullable: " . ($schema->isNullable('metadata') ? 'yes' : 'no') . "\n";
|
|
echo " Is 'count' nullable: " . ($schema->isNullable('count') ? 'yes' : 'no') . "\n";
|
|
echo " All fields: " . json_encode($schema->getFields()) . "\n";
|
|
echo "✓ DerivedSchema helper methods work correctly\n";
|
|
|
|
// Test 8: ValidationResult for non-throwing checks
|
|
echo "\nTest 8: ValidationResult for Non-Throwing Checks\n";
|
|
echo "-------------------------------------------------\n";
|
|
$result = $validator->check($newData, $schema);
|
|
if ($result->isValid()) {
|
|
echo "✓ Valid data check returns valid result\n";
|
|
echo " Error count: " . $result->getErrorCount() . "\n";
|
|
} else {
|
|
echo "✗ Valid data should pass check\n";
|
|
exit(1);
|
|
}
|
|
|
|
$result = $validator->check($invalidData, $schema);
|
|
if ($result->isFailed()) {
|
|
echo "✓ Invalid data check returns failed result\n";
|
|
echo " Error count: " . $result->getErrorCount() . "\n";
|
|
echo " Errors: " . json_encode($result->getErrors()) . "\n";
|
|
echo " Field errors: " . json_encode($result->getFieldErrors()) . "\n";
|
|
} else {
|
|
echo "✗ Invalid data should fail check\n";
|
|
exit(1);
|
|
}
|
|
|
|
echo "\n=== All Tests Passed! ===\n";
|
|
echo "\nSummary:\n";
|
|
echo " ✓ Schema derivation from component data\n";
|
|
echo " ✓ Valid state passes validation\n";
|
|
echo " ✓ Type mismatch detection\n";
|
|
echo " ✓ Missing field detection\n";
|
|
echo " ✓ Unexpected field detection\n";
|
|
echo " ✓ SchemaCache stores and retrieves schemas\n";
|
|
echo " ✓ DerivedSchema helper methods\n";
|
|
echo " ✓ ValidationResult for non-throwing checks\n";
|
|
echo "\nState Validation Implementation: COMPLETE\n";
|