Files
michaelschiemer/tests/Unit/Framework/Development/HotReload/HotReloadServerTest.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- 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.
2025-10-25 19:18:37 +02:00

293 lines
14 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Framework\Development\HotReload;
use App\Framework\Development\HotReload\FileChangeEvent;
use App\Framework\Development\HotReload\FileChangeType;
use App\Framework\Development\HotReload\HotReloadServer;
use App\Framework\Development\HotReload\ReloadType;
describe('HotReloadServer', function () {
it('determines full reload for PHP files', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('determineReloadType');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/src/Controller/UserController.php');
$reloadType = $method->invoke($hotReloadServer, $event);
expect($reloadType)->toBe(ReloadType::FULL);
});
it('determines CSS reload for CSS files', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('determineReloadType');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/resources/css/app.css');
$reloadType = $method->invoke($hotReloadServer, $event);
expect($reloadType)->toBe(ReloadType::CSS);
});
it('determines HMR reload for JavaScript files', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('determineReloadType');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/resources/js/app.js');
$reloadType = $method->invoke($hotReloadServer, $event);
expect($reloadType)->toBe(ReloadType::HMR);
});
it('determines HMR reload for TypeScript files', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('determineReloadType');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/resources/js/module.ts');
$reloadType = $method->invoke($hotReloadServer, $event);
expect($reloadType)->toBe(ReloadType::HMR);
});
it('determines full reload for view files', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('determineReloadType');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/resources/views/home.view.php');
$reloadType = $method->invoke($hotReloadServer, $event);
expect($reloadType)->toBe(ReloadType::FULL);
});
it('should clear cache for config changes', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('shouldClearCache');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/config/app.php');
$shouldClear = $method->invoke($hotReloadServer, $event);
expect($shouldClear)->toBeTrue();
});
it('should clear cache for controller changes', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('shouldClearCache');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/src/Controller/UserController.php');
$shouldClear = $method->invoke($hotReloadServer, $event);
expect($shouldClear)->toBeTrue();
});
it('should clear cache for route changes', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('shouldClearCache');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/src/Router/WebRoutes.php');
$shouldClear = $method->invoke($hotReloadServer, $event);
expect($shouldClear)->toBeTrue();
});
it('should clear cache for view changes', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('shouldClearCache');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/resources/views/components/header.view.php');
$shouldClear = $method->invoke($hotReloadServer, $event);
expect($shouldClear)->toBeTrue();
});
it('should not clear cache for regular PHP files', function () {
$server = new \ReflectionClass(HotReloadServer::class);
$method = $server->getMethod('shouldClearCache');
$fileWatcher = new class extends \App\Framework\Filesystem\FileWatcher {
public function __construct() {}
};
$sseStream = new class implements \App\Framework\Http\SseStreamInterface {
public function start($headers, $status, array $initialEvents = []): void {}
public function sendEvent($event): void {}
public function send(string $data, ?string $event = null, ?string $id = null, ?int $retry = null): void {}
public function sendJson(array $data, ?string $event = null, ?string $id = null): void {}
public function sendHeartbeat(?string $id = null): void {}
public function sendRetry(int $milliseconds): void {}
public function close(?string $message = null): void {}
public function isConnectionActive(): bool { return true; }
public function isActive(): bool { return true; }
};
$hotReloadServer = new HotReloadServer($fileWatcher, $sseStream);
$event = FileChangeEvent::modified('/var/www/html/src/Service/UserService.php');
$shouldClear = $method->invoke($hotReloadServer, $event);
expect($shouldClear)->toBeFalse();
});
});