Passed
Push — main ( fe77ac...556dc2 )
by Chema
02:14
created

RouteTest::test_multiple_optional_argument()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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