Skip to content

Commit 04ab266

Browse files
authored
Merge pull request #13 from clebsonsh/feat/add-support-to-handler-has-a-string-class
feat/add-support-to-handler-has-a-string-class
2 parents b8ed614 + 101bbc6 commit 04ab266

12 files changed

Lines changed: 73 additions & 51 deletions

File tree

app/Routes/api.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
use Infra\Http\Router;
77

88
return function (Router $router) {
9-
$router->post('/api/posts/{id}', new PostHandler);
9+
$router->post('/api/posts/{id}', PostHandler::class);
1010
};

app/Routes/web.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
use Infra\Http\Router;
77

88
return function (Router $router) {
9-
$router->get('/', new HomeHandler);
9+
$router->get('/', HomeHandler::class);
1010
};

infra/Http/Request.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,10 @@ private static function getHeadersFromGlobals(): array
9696
return $headers;
9797
}
9898

99-
/**
100-
* @template T of RequestDtoInterface
101-
*
102-
* @param class-string<T> $requestDto
103-
* @return T
104-
*/
99+
/** @param class-string<RequestDtoInterface> $requestDto */
105100
public function getData(string $requestDto): RequestDtoInterface
106101
{
107-
/** @var T $requestData */
108-
$requestData = $requestDto::fromRequestData($this->data);
109-
110-
return $requestData;
102+
return $requestDto::fromRequestData($this->data);
111103
}
112104

113105
public function getPath(): string

infra/Http/Route.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ class Route
1414

1515
private string $pattern;
1616

17+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
1718
public function __construct(
1819
private readonly string $path,
1920
private readonly HttpMethod $method,
20-
private readonly RequestHandlerInterface $handler
21+
private readonly string|RequestHandlerInterface $handler
2122
) {
2223
$this->params = [];
2324
$this->pattern = $this->compilePath();
@@ -30,7 +31,8 @@ private function compilePath(): string
3031
return '#^'.$pattern.'$#';
3132
}
3233

33-
public function getHandler(): RequestHandlerInterface
34+
/** @return class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
35+
public function getHandler(): string|RequestHandlerInterface
3436
{
3537
return $this->handler;
3638
}

infra/Http/Router.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,32 @@ public function __construct(
2626
private readonly Request $request,
2727
) {}
2828

29-
public function get(string $path, RequestHandlerInterface $handler): void
29+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
30+
public function get(string $path, string|RequestHandlerInterface $handler): void
3031
{
3132
$this->register($path, HttpMethod::GET, $handler);
3233
}
3334

34-
public function post(string $path, RequestHandlerInterface $handler): void
35+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
36+
public function post(string $path, string|RequestHandlerInterface $handler): void
3537
{
3638
$this->register($path, HttpMethod::POST, $handler);
3739
}
3840

39-
public function put(string $path, RequestHandlerInterface $handler): void
41+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
42+
public function put(string $path, string|RequestHandlerInterface $handler): void
4043
{
4144
$this->register($path, HttpMethod::PUT, $handler);
4245
}
4346

44-
public function patch(string $path, RequestHandlerInterface $handler): void
47+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
48+
public function patch(string $path, string|RequestHandlerInterface $handler): void
4549
{
4650
$this->register($path, HttpMethod::PATCH, $handler);
4751
}
4852

49-
public function delete(string $path, RequestHandlerInterface $handler): void
53+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
54+
public function delete(string $path, string|RequestHandlerInterface $handler): void
5055
{
5156
$this->register($path, HttpMethod::DELETE, $handler);
5257
}
@@ -56,7 +61,8 @@ public function redirect(string $from, string $to, int $status = 302): void
5661
$this->get($from, new RedirectHandler($to, $status));
5762
}
5863

59-
private function register(string $path, HttpMethod $httpMethod, RequestHandlerInterface $handler): void
64+
/** @param class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
65+
private function register(string $path, HttpMethod $httpMethod, string|RequestHandlerInterface $handler): void
6066
{
6167
$this->routes[] = new Route($path, $httpMethod, $handler);
6268
}
@@ -65,8 +71,14 @@ public function handleRequest(): Response
6571
{
6672
try {
6773
$route = $this->getRoute();
74+
6875
$this->request->setParams($route->getParams());
69-
$response = $route->getHandler()->handle($this->request);
76+
77+
/** @var class-string<RequestHandlerInterface>|RequestHandlerInterface $handler */
78+
$handler = $route->getHandler();
79+
$response = is_string($handler)
80+
? (new $handler)->handle($this->request)
81+
: $handler->handle($this->request);
7082
} catch (NotFoundException) {
7183
$response = (new NotFoundHandler)->handle($this->request);
7284
} catch (MethodNotAllowedException) {

tests/Unit/app/Handlers/HomeHandlerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Infra\Http\Router;
1111

1212
describe('Web', function () {
13-
it('should return home page', function () {
13+
it('returns a successful response for the home page', function () {
1414
$request = new Request('/', HttpMethod::GET, []);
1515
$router = new Router($request);
1616

tests/Unit/app/Handlers/PostHandlerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Infra\Http\Router;
1111

1212
describe('Api', function () {
13-
it('should return a json response', function () {
13+
it('returns a JSON response with data and params for a POST request', function () {
1414
$data = [
1515
'title' => 'Test title',
1616
'content' => 'Test content',

tests/Unit/infra/Http/EmitterTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use Infra\Http\Response;
77

88
describe('Emitter', function () {
9-
it('should emit the status code, headers, and body from a response', function () {
9+
it('emits the status code, headers, and body from a response', function () {
1010
$response = new Response(
1111
status: 404,
1212
body: '{"error":"Not Found"}',
@@ -24,7 +24,7 @@
2424
expect($output)->toBe('{"error":"Not Found"}');
2525
});
2626

27-
it('should handle a response with no headers and an empty body', function () {
27+
it('handles a response with no headers and an empty body', function () {
2828
$response = new Response(status: 204, body: '', headers: []);
2929
$emitter = new Emitter;
3030

tests/Unit/infra/Http/RequestTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
unset($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'], $_SERVER['HTTP_ACCEPT']);
1111
});
1212

13-
it('should create a request from globals', function () {
13+
it('creates a Request instance from PHP superglobals', function () {
1414
$_SERVER['REQUEST_METHOD'] = 'GET';
1515
$_SERVER['REQUEST_URI'] = '/test';
1616

@@ -19,7 +19,7 @@
1919
expect($request)->toBeInstanceOf(Request::class);
2020
});
2121

22-
it('should get accept headers from globals', function () {
22+
it('extracts headers from PHP superglobals', function () {
2323
$_SERVER['REQUEST_METHOD'] = 'GET';
2424
$_SERVER['REQUEST_URI'] = '/test';
2525
$_SERVER['HTTP_ACCEPT'] = 'application/json';
@@ -30,7 +30,7 @@
3030
->and($request->getHeaders())->toBe(['accept' => 'application/json']);
3131
});
3232

33-
it('should throw an exception if request method is not defined', function () {
33+
it('throws a RuntimeException if REQUEST_METHOD is not defined', function () {
3434
$_SERVER['REQUEST_URI'] = '/test';
3535

3636
expect(fn () => Request::createFromGlobals())
@@ -39,15 +39,15 @@
3939
});
4040

4141
describe('Getters', function () {
42-
it('should return the correct request path', function () {
42+
it('getPath returns the correct request path', function () {
4343
$request = prepareRequest(path: '/users/1');
4444

4545
expect($request->getPath())
4646
->toBeString()
4747
->toBe('/users/1');
4848
});
4949

50-
it('should return the correct request method', function () {
50+
it('getMethod returns the correct request method', function () {
5151
$request = prepareRequest(method: HttpMethod::POST);
5252

5353
expect($request->getMethod())

tests/Unit/infra/Http/ResponseTest.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
use Infra\Http\Response;
66

77
describe('Constructor', function () {
8-
it('should create a response with default values', function () {
8+
it('creates a response with default values', function () {
99
$response = new Response;
1010

1111
expect($response->getStatus())->toBe(200)
1212
->and($response->getHeaders())->toBe([])
1313
->and($response->getBody())->toBe('');
1414
});
1515

16-
it('should create a response with custom values', function () {
16+
it('creates a response with custom values', function () {
1717
$response = new Response(
1818
status: 404,
1919
body: 'Not Found',
@@ -27,7 +27,7 @@
2727
});
2828

2929
describe('JSON Factory', function () {
30-
it('should create a JSON response with a 200 status by default', function () {
30+
it('creates a JSON response with a 200 status by default', function () {
3131
$data = ['user' => 'John Doe', 'id' => 123];
3232
$response = Response::json($data);
3333

@@ -36,7 +36,7 @@
3636
->and($response->getBody())->toBe(json_encode($data));
3737
});
3838

39-
it('should create a JSON response with a custom status', function () {
39+
it('creates a JSON response with a custom status', function () {
4040
$data = ['error' => 'Invalid input'];
4141
$response = Response::json($data, 422);
4242

@@ -45,15 +45,15 @@
4545
->and($response->getBody())->toBe(json_encode($data));
4646
});
4747

48-
it('should handle an empty array for a JSON response', function () {
48+
it('handles an empty array for a JSON response', function () {
4949
$response = Response::json([]);
5050

5151
expect($response->getBody())->toBe('[]');
5252
});
5353
});
5454

5555
describe('HTML Factory', function () {
56-
it('should create an HTML response with a 200 status by default', function () {
56+
it('creates an HTML response with a 200 status by default', function () {
5757
$html = '<h1>Hello, World!</h1>';
5858
$response = Response::html($html);
5959

@@ -62,7 +62,7 @@
6262
->and($response->getBody())->toBe($html);
6363
});
6464

65-
it('should create an HTML response with a custom status', function () {
65+
it('creates an HTML response with a custom status', function () {
6666
$html = '<h1>Unauthorized</h1>';
6767
$response = Response::html($html, 401);
6868

0 commit comments

Comments
 (0)