3 * Tests for the PathRouter parsing
6 class PathRouterTest
extends MediaWikiTestCase
{
8 public function setUp() {
9 $router = new PathRouter
;
10 $router->add("/wiki/$1");
11 $this->basicRouter
= $router;
15 * Test basic path parsing
17 public function testBasic() {
18 $matches = $this->basicRouter
->parse( "/wiki/Foo" );
19 $this->assertEquals( $matches, array( 'title' => "Foo" ) );
23 * Test loose path auto-$1
25 public function testLoose() {
26 $router = new PathRouter
;
27 $router->add("/"); # Should be the same as "/$1"
28 $matches = $router->parse( "/Foo" );
29 $this->assertEquals( $matches, array( 'title' => "Foo" ) );
31 $router = new PathRouter
;
32 $router->add("/wiki"); # Should be the same as /wiki/$1
33 $matches = $router->parse( "/wiki/Foo" );
34 $this->assertEquals( $matches, array( 'title' => "Foo" ) );
36 $router = new PathRouter
;
37 $router->add("/wiki/"); # Should be the same as /wiki/$1
38 $matches = $router->parse( "/wiki/Foo" );
39 $this->assertEquals( $matches, array( 'title' => "Foo" ) );
43 * Test to ensure that path is based on specifity, not order
45 public function testOrder() {
46 $router = new PathRouter
;
48 $router->add("/a/$1");
49 $router->add("/b/$1");
50 $matches = $router->parse( "/a/Foo" );
51 $this->assertEquals( $matches, array( 'title' => "Foo" ) );
53 $router = new PathRouter
;
54 $router->add("/b/$1");
55 $router->add("/a/$1");
57 $matches = $router->parse( "/a/Foo" );
58 $this->assertEquals( $matches, array( 'title' => "Foo" ) );
62 * Test the handling of key based arrays with a url parameter
64 public function testKeyParameter() {
65 $router = new PathRouter
;
66 $router->add( array( 'edit' => "/edit/$1" ), array( 'action' => '$key' ) );
67 $matches = $router->parse( "/edit/Foo" );
68 $this->assertEquals( $matches, array( 'title' => "Foo", 'action' => 'edit' ) );
72 * Test the handling of $2 inside paths
74 public function testAdditionalParameter() {
76 $router = new PathRouter
;
77 $router->add( '/$2/$1', array( 'test' => '$2' ) );
78 $matches = $router->parse( "/asdf/Foo" );
79 $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'asdf' ) );
83 * Test additional restricted value parameter
85 public function testRestrictedValue() {
86 $router = new PathRouter
;
87 $router->add( '/$2/$1',
88 array( 'test' => '$2' ),
89 array( '$2' => array( 'a', 'b' ) )
91 $router->add( '/$2/$1',
92 array( 'test2' => '$2' ),
95 $router->add( '/$1' );
97 $matches = $router->parse( "/asdf/Foo" );
98 $this->assertEquals( $matches, array( 'title' => "asdf/Foo" ) );
100 $matches = $router->parse( "/a/Foo" );
101 $this->assertEquals( $matches, array( 'title' => "Foo", 'test' => 'a' ) );
103 $matches = $router->parse( "/c/Foo" );
104 $this->assertEquals( $matches, array( 'title' => "Foo", 'test2' => 'c' ) );
107 public function callbackForTest( &$matches, $data ) {
108 $matches['x'] = $data['$1'];
109 $matches['foo'] = $data['foo'];
112 public function testCallback() {
113 $router = new PathRouter
;
115 array( 'a' => 'b', 'data:foo' => 'bar' ),
116 array( 'callback' => array( $this, 'callbackForTest' ) )
118 $matches = $router->parse( '/Foo' );
119 $this->assertEquals( $matches, array(
128 * Test to ensure that matches are not made if a parameter expects nonexistent input
130 public function testFail() {
131 $router = new PathRouter
;
132 $router->add( "/wiki/$1", array( 'title' => "$1$2" ) );
133 $matches = $router->parse( "/wiki/A" );
134 $this->assertEquals( array(), $matches );
138 * Test to ensure weight of paths is handled correctly
140 public function testWeight() {
141 $router = new PathRouter
;
142 $router->addStrict( "/Bar", array( 'ping' => 'pong' ) );
143 $router->add( "/asdf-$1", array( 'title' => 'qwerty-$1' ) );
144 $router->add( "/$1" );
145 $router->add( "/qwerty-$1", array( 'title' => 'asdf-$1' ) );
146 $router->addStrict( "/Baz", array( 'marco' => 'polo' ) );
147 $router->add( "/a/$1" );
148 $router->add( "/asdf/$1" );
149 $router->add( "/$2/$1", array( 'unrestricted' => '$2' ) );
150 $router->add( array( 'qwerty' => "/qwerty/$1" ), array( 'qwerty' => '$key' ) );
151 $router->add( "/$2/$1", array( 'restricted-to-y' => '$2' ), array( '$2' => 'y' ) );
154 "/Foo" => array( 'title' => "Foo" ),
155 "/Bar" => array( 'ping' => 'pong' ),
156 "/Baz" => array( 'marco' => 'polo' ),
157 "/asdf-foo" => array( 'title' => "qwerty-foo" ),
158 "/qwerty-bar" => array( 'title' => "asdf-bar" ),
159 "/a/Foo" => array( 'title' => "Foo" ),
160 "/asdf/Foo" => array( 'title' => "Foo" ),
161 "/qwerty/Foo" => array( 'title' => "Foo", 'qwerty' => 'qwerty' ),
162 "/baz/Foo" => array( 'title' => "Foo", 'unrestricted' => 'baz' ),
163 "/y/Foo" => array( 'title' => "Foo", 'restricted-to-y' => 'y' ),
164 ) as $path => $result ) {
165 $this->assertEquals( $router->parse( $path ), $result );
170 * Make sure the router handles titles like Special:Recentchanges correctly
172 public function testSpecial() {
173 $matches = $this->basicRouter
->parse( "/wiki/Special:Recentchanges" );
174 $this->assertEquals( $matches, array( 'title' => "Special:Recentchanges" ) );
178 * Make sure the router decodes urlencoding properly
180 public function testUrlencoding() {
181 $matches = $this->basicRouter
->parse( "/wiki/Title_With%20Space" );
182 $this->assertEquals( $matches, array( 'title' => "Title_With Space" ) );
185 public function dataRegexpChars() {
195 * Make sure the router doesn't break on special characters like $ used in regexp replacements
196 * @dataProvider dataRegexpChars
198 public function testRegexpChars( $char ) {
199 $matches = $this->basicRouter
->parse( "/wiki/$char" );
200 $this->assertEquals( $matches, array( 'title' => "$char" ) );
204 * Make sure the router handles characters like +&() properly
206 public function testCharacters() {
207 $matches = $this->basicRouter
->parse( "/wiki/Plus+And&Dollar\\Stuff();[]{}*" );
208 $this->assertEquals( $matches, array( 'title' => "Plus+And&Dollar\\Stuff();[]{}*" ) );
212 * Make sure the router handles unicode characters correctly
213 * @depends testSpecial
214 * @depends testUrlencoding
215 * @depends testCharacters
217 public function testUnicode() {
218 $matches = $this->basicRouter
->parse( "/wiki/Spécial:Modifications_récentes" );
219 $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) );
221 $matches = $this->basicRouter
->parse( "/wiki/Sp%C3%A9cial:Modifications_r%C3%A9centes" );
222 $this->assertEquals( $matches, array( 'title' => "Spécial:Modifications_récentes" ) );
226 * Ensure the router doesn't choke on long paths.
228 public function testLength() {
229 $matches = $this->basicRouter
->parse( "/wiki/Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." );
230 $this->assertEquals( $matches, array( 'title' => "Lorem_ipsum_dolor_sit_amet,_consectetur_adipisicing_elit,_sed_do_eiusmod_tempor_incididunt_ut_labore_et_dolore_magna_aliqua._Ut_enim_ad_minim_veniam,_quis_nostrud_exercitation_ullamco_laboris_nisi_ut_aliquip_ex_ea_commodo_consequat._Duis_aute_irure_dolor_in_reprehenderit_in_voluptate_velit_esse_cillum_dolore_eu_fugiat_nulla_pariatur._Excepteur_sint_occaecat_cupidatat_non_proident,_sunt_in_culpa_qui_officia_deserunt_mollit_anim_id_est_laborum." ) );
235 * Ensure that the php passed site of parameter values are not urldecoded
237 public function testPatternUrlencoding() {
238 $router = new PathRouter
;
239 $router->add( "/wiki/$1", array( 'title' => '%20:$1' ) );
240 $matches = $router->parse( "/wiki/Foo" );
241 $this->assertEquals( $matches, array( 'title' => '%20:Foo' ) );
245 * Ensure that raw parameter values do not have any variable replacements or urldecoding
247 public function testRawParamValue() {
248 $router = new PathRouter
;
249 $router->add( "/wiki/$1", array( 'title' => array( 'value' => 'bar%20$1' ) ) );
250 $matches = $router->parse( "/wiki/Foo" );
251 $this->assertEquals( $matches, array( 'title' => 'bar%20$1' ) );