RealExampleBench::provideStaticRoutes()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 16
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 24
rs 9.7333
1
<?php declare(strict_types=1);
2
3
/*
4
 * This file is part of Flight Routing.
5
 *
6
 * PHP version 8.0 and above required
7
 *
8
 * @author    Divine Niiquaye Ibok <[email protected]>
9
 * @copyright 2019 Divine Niiquaye Ibok (https://divinenii.com/)
10
 * @license   https://opensource.org/licenses/BSD-3-Clause License
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
16
namespace Flight\Routing\Tests\Benchmarks;
17
18
use Flight\Routing\Exceptions\MethodNotAllowedException;
19
use Flight\Routing\Interfaces\RouteMatcherInterface;
20
use Flight\Routing\{RouteCollection, Router};
21
22
/**
23
 * @Groups({"real"})
24
 */
25
final class RealExampleBench extends RouteBench
26
{
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function createDispatcher(string $cache = null): RouteMatcherInterface
31
    {
32
        $router = new Router(null, $cache);
33
        $router->setCollection(static function (RouteCollection $routes): void {
34
            $routes->add('/', ['GET'])->bind('home');
35
            $routes->add('/page/{page_slug:[a-zA-Z0-9\-]+}', ['GET'])->bind('page.show');
36
            $routes->add('/about-us', ['GET'])->bind('about-us');
37
            $routes->add('/contact-us', ['GET'])->bind('contact-us');
38
            $routes->add('/contact-us', ['POST'])->bind('contact-us.submit');
39
            $routes->add('/blog', ['GET'])->bind('blog.index');
40
            $routes->add('/blog/recent', ['GET'])->bind('blog.recent');
41
            $routes->add('/blog/post/{post_slug:[a-zA-Z0-9\-]+}', ['GET'])->bind('blog.post.show');
42
            $routes->add('/blog/post/{post_slug:[a-zA-Z0-9\-]+}/comment', ['POST'])->bind('blog.post.comment');
43
            $routes->add('/shop', ['GET'])->bind('shop.index');
44
            $routes->add('/shop/category', ['GET'])->bind('shop.category.index');
45
            $routes->add('/shop/category/search/{filter_by:[a-zA-Z]+}:{filter_value}', ['GET'])->bind('shop.category.search');
46
            $routes->add('/shop/category/{category_id:\d+}', ['GET'])->bind('shop.category.show');
47
            $routes->add('/shop/category/{category_id:\d+}/product', ['GET'])->bind('shop.category.product.index');
48
            $routes->add('/shop/category/{category_id:\d+}/product/search/{filter_by:[a-zA-Z]+}:{filter_value}', ['GET'])->bind('shop.category.product.search');
49
            $routes->add('/shop/product', ['GET'])->bind('shop.product.index');
50
            $routes->any('/shop[/{type:\w+}[:{filter_by:\@.*}]')->bind('shop.api')->domain('api.shop.com');
51
            $routes->add('/shop/product/search/{filter_by:[a-zA-Z]+}:{filter_value}', ['GET'])->bind('shop.product.search');
52
            $routes->add('/shop/product/{product_id:\d+}', ['GET'])->bind('shop.product.show');
53
            $routes->add('/shop/cart', ['GET'])->bind('shop.cart.show');
54
            $routes->add('/shop/cart', ['PUT', 'DELETE'])->bind('shop.cart.add_remove');
55
            $routes->add('/shop/cart/checkout', ['GET', 'POST'])->bind('shop.cart.checkout');
56
            $routes->add('/admin/login', ['GET', 'POST'])->bind('admin.login');
57
            $routes->add('/admin/logout', ['GET'])->bind('admin.logout');
58
            $routes->add('/admin', ['GET'])->bind('admin.index');
59
            $routes->add('/admin/product', ['GET'])->bind('admin.product.index');
60
            $routes->add('/admin/product/create', ['GET'])->bind('admin.product.create');
61
            $routes->add('/admin/product', ['POST'])->bind('admin.product.store');
62
            $routes->add('/admin/product/{product_id:\d+}', ['GET', 'PUT', 'PATCH', 'DELETE'])->bind('admin.product');
63
            $routes->add('/admin/product/{product_id:\d+}/edit', ['GET'])->bind('admin.product.edit');
64
            $routes->add('/admin/category', ['GET', 'POST'])->bind('admin.category.index_store');
65
            $routes->add('/admin/category/create', ['GET'])->bind('admin.category.create');
66
            $routes->add('/admin/category/{category_id:\d+}', ['GET', 'PUT', 'PATCH', 'DELETE'])->bind('admin.category');
67
            $routes->add('/admin/category/{category_id:\d+}/edit', ['GET'])->bind('admin.category.edit');
68
            $routes->sort(); // Sort routes by giving more priority to static like routes
69
        });
70
71
        return $router;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function provideStaticRoutes(): iterable
78
    {
79
        yield 'first' => [
80
            'method' => 'GET',
81
            'route' => '/',
82
            'result' => ['handler' => null, 'prefix' => '/', 'path' => '/', 'methods' => ['GET' => true], 'name' => 'home'],
83
        ];
84
85
        yield 'middle' => [
86
            'method' => 'GET',
87
            'route' => '/shop/product',
88
            'result' => ['handler' => null, 'prefix' => '/shop/product', 'path' => '/shop/product', 'methods' => ['GET' => true], 'name' => 'shop.product.index'],
89
        ];
90
91
        yield 'last' => [
92
            'method' => 'GET',
93
            'route' => '/admin/category',
94
            'result' => ['handler' => null, 'prefix' => '/admin/category', 'path' => '/admin/category', 'methods' => ['GET' => true, 'POST' => true], 'name' => 'admin.category.index_store'],
95
        ];
96
97
        yield 'invalid-method' => [
98
            'method' => 'PUT',
99
            'route' => '/about-us',
100
            'result' => MethodNotAllowedException::class,
101
        ];
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function provideDynamicRoutes(): iterable
108
    {
109
        yield 'first' => [
110
            'method' => 'GET',
111
            'route' => '/page/hello-word',
112
            'result' => [
113
                'handler' => null,
114
                'prefix' => '/page',
115
                'path' => '/page/{page_slug:[a-zA-Z0-9\-]+}',
116
                'methods' => ['GET' => true],
117
                'name' => 'page.show',
118
                'arguments' => ['page_slug' => 'hello-word'],
119
            ],
120
        ];
121
122
        yield 'middle' => [
123
            'method' => 'GET',
124
            'route' => '//api.shop.com/shop/category_search:filter_by@furniture?value=chair',
125
            'result' => [
126
                'handler' => null,
127
                'hosts' => ['api.shop.com' => true],
128
                'prefix' => '/shop',
129
                'path' => '/shop[/{type:\w+}[:{filter_by:\@.*}]',
130
                'methods' => \array_fill_keys(Router::HTTP_METHODS_STANDARD, true),
131
                'name' => 'shop.api',
132
                'arguments' => ['type' => 'category_search', 'filter_by' => 'furniture'],
133
            ],
134
        ];
135
136
        yield 'last' => [
137
            'method' => 'GET',
138
            'route' => '/admin/category/123/edit',
139
            'result' => [
140
                'handler' => null,
141
                'prefix' => '/admin/category',
142
                'path' => '/admin/category/{category_id:\d+}/edit',
143
                'methods' => ['GET' => true],
144
                'name' => 'admin.category.edit',
145
                'arguments' => ['category_id' => '123'],
146
            ],
147
        ];
148
149
        yield 'invalid-method' => [
150
            'method' => 'PATCH',
151
            'route' => '/shop/category/123',
152
            'result' => MethodNotAllowedException::class,
153
        ];
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159
    public function provideOtherScenarios(): iterable
160
    {
161
        yield 'non-existent' => [
162
            'method' => 'GET',
163
            'route' => '/shop/product/awesome',
164
            'result' => null,
165
        ];
166
167
        yield 'longest-route' => [
168
            'method' => 'GET',
169
            'route' => '/shop/category/123/product/search/status:sale',
170
            'result' => [
171
                'handler' => null,
172
                'prefix' => '/admin/category/123/edit',
173
                'path' => '/shop/category/{category_id:\d+}/product/search/{filter_by:[a-zA-Z]+}:{filter_value}',
174
                'methods' => ['GET' => true],
175
                'name' => 'shop.category.product.search',
176
                'arguments' => ['category_id' => '123', 'filter_by' => 'status', 'filter_value' => 'sale'],
177
            ],
178
        ];
179
    }
180
}
181