Passed
Pull Request — main (#4)
by Chema
02:20
created

RouteTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GacelaTest\Unit\Router;
6
7
use Gacela\Router\Request;
8
use Gacela\Router\Route;
9
use Gacela\Router\RoutingConfigurator;
10
use Generator;
11
use PHPUnit\Framework\TestCase;
12
13
final class RouteTest extends TestCase
14
{
15
    private const PROVIDER_TRIES = 10;
16
17
    protected function setUp(): void
18
    {
19
        Request::resetCache();
20
    }
21
22
    public function test_it_should_respond_if_everything_matches(): void
23
    {
24
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
25
        $_SERVER['REQUEST_METHOD'] = 'GET';
26
27
        $this->expectOutputString('Expected!');
28
29
        Route::configure(static function (RoutingConfigurator $routes): void {
30
            $routes->get('expected/uri', FakeController::class, 'basicAction');
31
        });
32
    }
33
34
    public function test_it_should_not_respond_if_the_uri_does_not_matches(): void
35
    {
36
        $_SERVER['REQUEST_URI'] = 'https://example.org/unexpected/uri';
37
        $_SERVER['REQUEST_METHOD'] = 'GET';
38
39
        $this->expectOutputString('');
40
41
        Route::configure(static function (RoutingConfigurator $routes): void {
42
            $routes->get('other/uri', FakeController::class, 'basicAction');
43
        });
44
    }
45
46
    public function test_it_should_not_respond_if_the_method_does_not_matches(): void
47
    {
48
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
49
        $_SERVER['REQUEST_METHOD'] = 'GET';
50
51
        $this->expectOutputString('');
52
53
        Route::configure(static function (RoutingConfigurator $routes): void {
54
            $routes->post('expected/uri', FakeController::class, 'basicAction');
55
        });
56
    }
57
58
    public function test_it_should_pass_many_params_to_the_action(): void
59
    {
60
        /** @var list<string> $params */
61
        $params = ['foo','bar','baz'];
62
63
        $_SERVER['REQUEST_URI'] = "https://example.org/{$params[0]}/{$params[1]}/{$params[2]}";
64
        $_SERVER['REQUEST_METHOD'] = 'GET';
65
66
        $this->expectOutputString("The params are '{$params[0]}', '{$params[1]}' and '{$params[2]}'!");
67
68
        Route::configure(static function (RoutingConfigurator $routes): void {
69
            $routes->get('{firstParam}/{secondParam}/{thirdParam}', FakeController::class, 'manyParamsAction');
70
        });
71
    }
72
73
    public function test_it_should_pass_associated_params_by_name_to_the_action(): void
74
    {
75
        /** @var list<string> $params */
76
        $params = ['foo','bar','baz'];
77
78
        $_SERVER['REQUEST_URI'] = "https://example.org/{$params[0]}/{$params[1]}/{$params[2]}";
79
        $_SERVER['REQUEST_METHOD'] = 'GET';
80
81
        $this->expectOutputString("The params are '{$params[1]}', '{$params[0]}' and '{$params[2]}'!");
82
83
        Route::configure(static function (RoutingConfigurator $routes): void {
84
            $routes->get('{secondParam}/{firstParam}/{thirdParam}', FakeController::class, 'manyParamsAction');
85
        });
86
    }
87
88
    /**
89
     * @dataProvider stringProvider
90
     */
91
    public function test_it_should_pass_string_params_to_the_action(string $string): void
92
    {
93
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/string/is/{$string}";
94
        $_SERVER['REQUEST_METHOD'] = 'GET';
95
96
        $this->expectOutputString("The 'string' param is '{$string}'!");
97
98
        Route::configure(static function (RoutingConfigurator $routes): void {
99
            $routes->get('expected/string/is/{param}', FakeController::class, 'stringParamAction');
100
        });
101
    }
102
103
    public function stringProvider(): Generator
104
    {
105
        for ($try = 0; $try < self::PROVIDER_TRIES; ++$try) {
106
            $randomString = (string)'word-' . mt_rand();
107
            yield $randomString => ['string' => $randomString];
108
        }
109
    }
110
111
    /**
112
     * @dataProvider intProvider
113
     */
114
    public function test_it_should_pass_int_params_to_the_action(string $int): void
115
    {
116
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/integer/is/{$int}";
117
        $_SERVER['REQUEST_METHOD'] = 'GET';
118
119
        $this->expectOutputString("The 'int' param is '{$int}'!");
120
121
        Route::configure(static function (RoutingConfigurator $routes): void {
122
            $routes->get('expected/integer/is/{param}', FakeController::class, 'intParamAction');
123
        });
124
    }
125
126
    public function intProvider(): Generator
127
    {
128
        for ($try = 0; $try < self::PROVIDER_TRIES; ++$try) {
129
            $randomInt = (string)random_int(1, 9999);
130
            yield "#{$randomInt}" => ['int' => $randomInt];
131
        }
132
    }
133
134
    /**
135
     * @dataProvider floatProvider
136
     */
137
    public function test_it_should_pass_float_params_to_the_action(string $float): void
138
    {
139
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/float/is/{$float}";
140
        $_SERVER['REQUEST_METHOD'] = 'GET';
141
142
        $this->expectOutputString("The 'float' param is '{$float}'!");
143
144
        Route::configure(static function (RoutingConfigurator $routes): void {
145
            $routes->get('expected/float/is/{param}', FakeController::class, 'floatParamAction');
146
        });
147
    }
148
149
    public function floatProvider(): Generator
150
    {
151
        for ($try = 0; $try < self::PROVIDER_TRIES; ++$try) {
152
            $randomFloat = (string)mt_rand();
153
            yield "#{$randomFloat}" => ['float' => $randomFloat];
154
        }
155
    }
156
157
    /**
158
     * @dataProvider boolProvider
159
     */
160
    public function test_it_should_pass_bool_params_to_the_action(string $given, string $expected): void
161
    {
162
        $_SERVER['REQUEST_URI'] = "https://example.org/expected/bool/is/{$given}";
163
        $_SERVER['REQUEST_METHOD'] = 'GET';
164
165
        $this->expectOutputString("The 'bool' param is '{$expected}'!");
166
167
        Route::configure(static function (RoutingConfigurator $routes): void {
168
            $routes->get('expected/bool/is/{param}', FakeController::class, 'boolParamAction');
169
        });
170
    }
171
172
    public function boolProvider(): iterable
173
    {
174
        yield 'true' => ['given' => 'true', 'expected' => 'true'];
175
        yield 'false' => ['given' => 'false', 'expected' => 'false'];
176
        yield '1' => ['given' => '1', 'expected' => 'true'];
177
        yield '0' => ['given' => '0', 'expected' => 'false'];
178
    }
179
180
    public function test_it_should_respond_only_the_first_match(): void
181
    {
182
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
183
        $_SERVER['REQUEST_METHOD'] = 'GET';
184
185
        $this->expectOutputString('Expected!');
186
187
        Route::configure(static function (RoutingConfigurator $routes): void {
188
            $routes->get('expected/uri', FakeController::class, 'basicAction');
189
            $routes->get('expected/{param}', FakeController::class, 'stringParamAction');
190
        });
191
    }
192
193
    public function test_optional_argument(): void
194
    {
195
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
196
        $_SERVER['REQUEST_METHOD'] = 'GET';
197
198
        $this->expectOutputString('Expected!');
199
200
        Route::configure(static function (RoutingConfigurator $routes): void {
201
            $routes->get('optional/{param?}', FakeController::class, 'basicAction');
202
        });
203
    }
204
205
    public function test_multiple_optional_argument(): void
206
    {
207
        $_SERVER['REQUEST_URI'] = 'https://example.org/optional';
208
        $_SERVER['REQUEST_METHOD'] = 'GET';
209
210
        $this->expectOutputString('Expected!');
211
212
        Route::configure(static function (RoutingConfigurator $routes): void {
213
            $routes->get('optional/{param1?}/{param2?}', FakeController::class, 'basicAction');
214
        });
215
    }
216
217
    /**
218
     * @dataProvider anyHttpMethodProvider
219
     */
220
    public function test_any_http_method(string $httpMethod): void
221
    {
222
        $_SERVER['REQUEST_URI'] = 'https://example.org/expected/uri';
223
        $_SERVER['REQUEST_METHOD'] = $httpMethod;
224
225
        $this->expectOutputString('Expected!');
226
227
        Route::configure(static function (RoutingConfigurator $routes): void {
228
            $routes->any('expected/uri', FakeController::class, 'basicAction');
229
        });
230
    }
231
232
    public function anyHttpMethodProvider(): Generator
233
    {
234
        yield ['METHOD_GET' => Request::METHOD_GET];
235
        yield ['METHOD_CONNECT' => Request::METHOD_CONNECT];
236
        yield ['METHOD_DELETE' => Request::METHOD_DELETE];
237
        yield ['METHOD_HEAD' => Request::METHOD_HEAD];
238
        yield ['METHOD_OPTIONS' => Request::METHOD_OPTIONS];
239
        yield ['METHOD_PATCH' => Request::METHOD_PATCH];
240
        yield ['METHOD_POST' => Request::METHOD_POST];
241
        yield ['METHOD_PUT' => Request::METHOD_PUT];
242
        yield ['METHOD_TRACE' => Request::METHOD_TRACE];
243
    }
244
}
245