php-developer/src/Data/RouteTestResult.php
Snider 518305142e refactor: relocate module from app/Mod/Developer to src/
Move module to standard package structure with namespace change
from Mod\Developer to Core\Developer. Updates composer.json
autoload configuration accordingly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 16:25:31 +00:00

209 lines
5.5 KiB
PHP

<?php
declare(strict_types=1);
namespace Core\Developer\Data;
use Illuminate\Http\Response;
use Throwable;
/**
* Result of testing a route.
*
* Contains the HTTP response details, performance metrics, and any exception
* that occurred during the request.
*/
readonly class RouteTestResult
{
/**
* @param int $statusCode HTTP status code
* @param array<string, string> $headers Response headers
* @param string $body Response body
* @param float $responseTime Time taken in milliseconds
* @param int $memoryUsage Memory used in bytes
* @param Throwable|null $exception Exception if request failed
* @param string $method HTTP method used
* @param string $uri URI tested
*/
public function __construct(
public int $statusCode,
public array $headers,
public string $body,
public float $responseTime,
public int $memoryUsage,
public ?Throwable $exception = null,
public string $method = 'GET',
public string $uri = '',
) {}
/**
* Check if the request was successful (2xx status code).
*/
public function isSuccessful(): bool
{
return $this->statusCode >= 200 && $this->statusCode < 300;
}
/**
* Check if the request resulted in a redirect (3xx status code).
*/
public function isRedirect(): bool
{
return $this->statusCode >= 300 && $this->statusCode < 400;
}
/**
* Check if the request resulted in a client error (4xx status code).
*/
public function isClientError(): bool
{
return $this->statusCode >= 400 && $this->statusCode < 500;
}
/**
* Check if the request resulted in a server error (5xx status code).
*/
public function isServerError(): bool
{
return $this->statusCode >= 500;
}
/**
* Check if an exception occurred during the request.
*/
public function hasException(): bool
{
return $this->exception !== null;
}
/**
* Get the status text for the status code.
*/
public function getStatusText(): string
{
return Response::$statusTexts[$this->statusCode] ?? 'Unknown';
}
/**
* Get formatted response time.
*/
public function getFormattedResponseTime(): string
{
if ($this->responseTime < 1) {
return round($this->responseTime * 1000, 2).'μs';
}
if ($this->responseTime < 1000) {
return round($this->responseTime, 2).'ms';
}
return round($this->responseTime / 1000, 2).'s';
}
/**
* Get formatted memory usage.
*/
public function getFormattedMemoryUsage(): string
{
$bytes = $this->memoryUsage;
if ($bytes < 1024) {
return $bytes.' B';
}
if ($bytes < 1048576) {
return round($bytes / 1024, 2).' KB';
}
return round($bytes / 1048576, 2).' MB';
}
/**
* Get the content type from headers.
*/
public function getContentType(): string
{
$contentType = $this->headers['Content-Type']
?? $this->headers['content-type']
?? 'text/plain';
// Extract just the mime type (without charset, etc.)
return explode(';', $contentType)[0];
}
/**
* Check if response is JSON.
*/
public function isJson(): bool
{
return str_contains($this->getContentType(), 'json');
}
/**
* Check if response is HTML.
*/
public function isHtml(): bool
{
return str_contains($this->getContentType(), 'html');
}
/**
* Get formatted body for display.
*
* Attempts to pretty-print JSON responses.
*/
public function getFormattedBody(): string
{
if ($this->isJson()) {
$decoded = json_decode($this->body, true);
if (json_last_error() === JSON_ERROR_NONE) {
return json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
}
return $this->body;
}
/**
* Get body truncated to a maximum length.
*/
public function getTruncatedBody(int $maxLength = 10000): string
{
$body = $this->getFormattedBody();
if (strlen($body) <= $maxLength) {
return $body;
}
return substr($body, 0, $maxLength)."\n\n... (truncated, total: ".strlen($this->body).' bytes)';
}
/**
* Convert to array for serialisation.
*/
public function toArray(): array
{
return [
'status_code' => $this->statusCode,
'status_text' => $this->getStatusText(),
'method' => $this->method,
'uri' => $this->uri,
'headers' => $this->headers,
'body' => $this->body,
'body_length' => strlen($this->body),
'content_type' => $this->getContentType(),
'response_time' => $this->responseTime,
'response_time_formatted' => $this->getFormattedResponseTime(),
'memory_usage' => $this->memoryUsage,
'memory_usage_formatted' => $this->getFormattedMemoryUsage(),
'is_successful' => $this->isSuccessful(),
'is_json' => $this->isJson(),
'exception' => $this->exception ? [
'class' => get_class($this->exception),
'message' => $this->exception->getMessage(),
'file' => $this->exception->getFile(),
'line' => $this->exception->getLine(),
] : null,
];
}
}