OSDN Git Service

Merge pull request #66 from endelwar/full-test-coverage
[php-libraries/Router.git] / tests / src / PHPRouterTest / RouterTest.php
1 <?php
2 /**
3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14  *
15  * This software consists of voluntary contributions made by many individuals
16  * and is licensed under the MIT license.
17  */
18 namespace PHPRouterTest\Test;
19
20 use PHPRouter\Config;
21 use PHPRouter\Route;
22 use PHPRouter\Router;
23 use PHPRouter\RouteCollection;
24 use PHPUnit_Framework_TestCase;
25
26 class RouterTest extends PHPUnit_Framework_TestCase
27 {
28     /**
29      * @dataProvider matcherProvider
30      *
31      * @param Router $router
32      * @param string $path
33      * @param string $expected
34      */
35     public function testMatch($router, $path, $expected)
36     {
37         $this->assertEquals($expected, (bool)$router->match($path));
38     }
39
40     public function testMatchWrongMethod()
41     {
42         $router = $this->getRouter();
43         $this->assertFalse($router->match('/users', 'POST'));
44     }
45
46     public function testBasePathConfigIsSettedProperly()
47     {
48         $router = new Router(new RouteCollection);
49         $router->setBasePath('/webroot/');
50
51         $this->assertAttributeEquals('/webroot', 'basePath', $router);
52     }
53
54     public function testMatchRouterUsingBasePath()
55     {
56         $collection = new RouteCollection();
57         $collection->attach(new Route('/users/', array(
58             '_controller' => 'PHPRouter\Test\SomeController::usersCreate',
59             'methods' => 'GET'
60         )));
61
62         $router = new Router($collection);
63         $router->setBasePath('/localhost/webroot');
64
65         foreach ($this->serverProvider() as $server) {
66             $_SERVER = $server;
67             $this->assertTrue((bool)$router->matchCurrentRequest());
68         }
69     }
70
71     private function serverProvider()
72     {
73         return array(
74             array(
75                 'REQUEST_METHOD' => 'GET',
76                 'REQUEST_URI' => '/localhost/webroot/users/',
77                 'SCRIPT_NAME' => 'index.php'
78             ),
79             array(
80                 'REQUEST_METHOD' => 'GET',
81                 'REQUEST_URI' => '/localhost/webroot/users/?foo=bar&bar=foo',
82                 'SCRIPT_NAME' => 'index.php'
83             ),
84         );
85     }
86
87     public function testGetParamsInsideControllerMethod()
88     {
89         $collection = new RouteCollection();
90         $route = new Route(
91             '/page/:page_id',
92             array(
93                 '_controller' => 'PHPRouter\Test\SomeController::page',
94                 'methods' => 'GET'
95             )
96         );
97         $route->setFilters(array('page_id' => '([a-zA-Z]+)'), true);
98         $collection->attachRoute($route);
99
100         $router = new Router($collection);
101         $this->assertEquals(
102             array(array('page_id' => 'MySuperPage')),
103             $router->match('/page/MySuperPage')->getParameters()
104         );
105     }
106
107     public function testParamsWithDynamicFilterMatch()
108     {
109         $collection = new RouteCollection();
110         $route = new Route(
111             '/js/:filename.js',
112             array(
113                 '_controller' => 'PHPRouter\Test\SomeController::dynamicFilterUrlMatch',
114                 'methods' => 'GET',
115             )
116         );
117         $route->setFilters(array(':filename' => '([[:alnum:]\.]+)'), true);
118         $collection->attachRoute($route);
119
120         $router = new Router($collection);
121         $this->assertEquals(
122             array(array('filename' => 'someJsFile')),
123             $router->match('/js/someJsFile.js')->getParameters()
124         );
125
126         $this->assertEquals(
127             array(array('filename' => 'someJsFile.min')),
128             $router->match('/js/someJsFile.min.js')->getParameters()
129         );
130
131         $this->assertEquals(
132             array(array('filename' => 'someJsFile.min.js')),
133             $router->match('/js/someJsFile.min.js.js')->getParameters()
134         );
135     }
136
137     public function testParseConfig()
138     {
139         $config = Config::loadFromFile(__DIR__ . '/../../Fixtures/router.yaml');
140         $router = Router::parseConfig($config);
141         $this->assertAttributeEquals($config['base_path'], 'basePath', $router);
142     }
143
144     public function testGenerate()
145     {
146         $router = $this->getRouter();
147         $this->assertSame('/users/', $router->generate('users'));
148         $this->assertSame('/user/123', $router->generate('user', array('id' => 123)));
149     }
150
151     /**
152      * @expectedException \Exception
153      */
154     public function testGenerateNotExistent()
155     {
156         $router = $this->getRouter();
157         $this->assertSame('/notExists/', $router->generate('notThisRoute'));
158     }
159
160     /**
161      * @return Router
162      */
163     private function getRouter()
164     {
165         $collection = new RouteCollection();
166         $collection->attachRoute(new Route('/users/', array(
167             '_controller' => 'PHPRouter\Test\SomeController::usersCreate',
168             'methods' => 'GET',
169             'name' => 'users'
170         )));
171         $collection->attachRoute(new Route('/user/:id', array(
172             '_controller' => 'PHPRouter\Test\SomeController::user',
173             'methods' => 'GET',
174             'name' => 'user'
175         )));
176         $collection->attachRoute(new Route('/', array(
177             '_controller' => 'PHPRouter\Test\SomeController::indexAction',
178             'methods' => 'GET',
179             'name' => 'index'
180         )));
181
182         return new Router($collection);
183     }
184
185     /**
186      * @return mixed[][]
187      */
188     public function matcherProvider1()
189     {
190         $router = $this->getRouter();
191
192         return array(
193             array($router, '', true),
194             array($router, '/', true),
195             array($router, '/aaa', false),
196             array($router, '/users', true),
197             array($router, '/user/1', true),
198             array($router, '/user/%E3%81%82', true),
199         );
200     }
201
202     /**
203      * @return mixed[][]
204      */
205     public function matcherProvider2()
206     {
207         $router = $this->getRouter();
208         $router->setBasePath('/api');
209
210         return array(
211             array($router, '', false),
212             array($router, '/', false),
213             array($router, '/aaa', false),
214             array($router, '/users', false),
215             array($router, '/user/1', false),
216             array($router, '/user/%E3%81%82', false),
217             array($router, '/api', true),
218             array($router, '/api/aaa', false),
219             array($router, '/api/users', true),
220             array($router, '/api/user/1', true),
221             array($router, '/api/user/%E3%81%82', true),
222         );
223     }
224
225     /**
226      * @return string[]
227      */
228     public function matcherProvider()
229     {
230         return array_merge($this->matcherProvider1(), $this->matcherProvider2());
231     }
232 }