RegexTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * @category Zend
  4. * @package Zend_Controller
  5. * @subpackage UnitTests
  6. */
  7. require_once dirname(__FILE__) . '/../../../../TestHelper.php';
  8. /** Zend_Controller_Router_Route_Regex */
  9. require_once 'Zend/Controller/Router/Route/Regex.php';
  10. /**
  11. * @category Zend
  12. * @package Zend_Controller
  13. * @subpackage UnitTests
  14. */
  15. class Zend_Controller_Router_Route_RegexTest extends PHPUnit_Framework_TestCase
  16. {
  17. public function testStaticMatch()
  18. {
  19. $route = new Zend_Controller_Router_Route_Regex('users/all');
  20. $values = $route->match('users/all');
  21. $this->assertSame(array(), $values);
  22. }
  23. public function testStaticUTFMatch()
  24. {
  25. $route = new Zend_Controller_Router_Route_Regex('żółć');
  26. $values = $route->match('żółć');
  27. $this->assertSame(array(), $values);
  28. }
  29. public function testURLDecode()
  30. {
  31. $route = new Zend_Controller_Router_Route_Regex('żółć');
  32. $values = $route->match('%C5%BC%C3%B3%C5%82%C4%87');
  33. $this->assertSame(array(), $values);
  34. }
  35. public function testStaticNoMatch()
  36. {
  37. $route = new Zend_Controller_Router_Route_Regex('users/a/martel');
  38. $values = $route->match('users/a');
  39. $this->assertSame(false, $values);
  40. }
  41. public function testStaticMatchWithDefaults()
  42. {
  43. $route = new Zend_Controller_Router_Route_Regex('users/all', array('controller' => 'ctrl'));
  44. $values = $route->match('users/all');
  45. $this->assertSame(1, count($values));
  46. $this->assertSame('ctrl', $values['controller']);
  47. }
  48. public function testRootRoute()
  49. {
  50. $route = new Zend_Controller_Router_Route_Regex('');
  51. $values = $route->match('/');
  52. $this->assertSame(array(), $values);
  53. }
  54. public function testVariableMatch()
  55. {
  56. $route = new Zend_Controller_Router_Route_Regex('users/(.+)');
  57. $values = $route->match('users/martel');
  58. $this->assertSame(1, count($values));
  59. $this->assertSame('martel', $values[1]);
  60. }
  61. public function testDoubleMatch()
  62. {
  63. $route = new Zend_Controller_Router_Route_Regex('users/(user_(\d+).html)');
  64. $values = $route->match('users/user_1354.html');
  65. $this->assertSame(2, count($values));
  66. $this->assertSame('user_1354.html', $values[1]);
  67. $this->assertSame('1354', $values[2]);
  68. }
  69. public function testNegativeMatch()
  70. {
  71. $route = new Zend_Controller_Router_Route_Regex('((?!admin|moderator).+)',
  72. array('module' => 'index', 'controller' => 'index'),
  73. array(1 => 'action')
  74. );
  75. $values = $route->match('users');
  76. $this->assertSame(3, count($values));
  77. $this->assertSame('index', $values['module']);
  78. $this->assertSame('index', $values['controller']);
  79. $this->assertSame('users', $values['action']);
  80. }
  81. public function testNumericDefault()
  82. {
  83. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array(1 => 'martel'));
  84. $values = $route->match('users');
  85. $this->assertSame(1, count($values));
  86. $this->assertSame('martel', $values[1]);
  87. }
  88. public function testVariableMatchWithNumericDefault()
  89. {
  90. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array(1 => 'martel'));
  91. $values = $route->match('users/vicki');
  92. $this->assertSame(1, count($values));
  93. $this->assertSame('vicki', $values[1]);
  94. }
  95. public function testNamedVariableMatch()
  96. {
  97. $route = new Zend_Controller_Router_Route_Regex('users/(?P<username>.+)');
  98. $values = $route->match('users/martel');
  99. $this->assertSame(1, count($values));
  100. $this->assertSame('martel', $values[1]);
  101. }
  102. public function testMappedVariableMatch()
  103. {
  104. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, array(1 => 'username'));
  105. $values = $route->match('users/martel');
  106. $this->assertSame(1, count($values));
  107. $this->assertSame('martel', $values['username']);
  108. }
  109. public function testMappedVariableWithDefault()
  110. {
  111. $route = new Zend_Controller_Router_Route_Regex('users(?:/(.+))?', array('username' => 'martel'), array(1 => 'username'));
  112. $values = $route->match('users');
  113. $this->assertSame(1, count($values));
  114. $this->assertSame('martel', $values['username']);
  115. }
  116. public function testMappedVariableWithNamedSubpattern()
  117. {
  118. $route = new Zend_Controller_Router_Route_Regex('users/(?P<name>.+)', null, array(1 => 'username'));
  119. $values = $route->match('users/martel');
  120. $this->assertSame(1, count($values));
  121. $this->assertSame('martel', $values['username']);
  122. }
  123. public function testOptionalVar()
  124. {
  125. $route = new Zend_Controller_Router_Route_Regex('users/(\w+)/?(?:p/(\d+))?', null, array(1 => 'username', 2 => 'page'));
  126. $values = $route->match('users/martel/p/1');
  127. $this->assertSame(2, count($values));
  128. $this->assertSame('martel', $values['username']);
  129. $this->assertSame('1', $values['page']);
  130. }
  131. public function testEmptyOptionalVar()
  132. {
  133. $route = new Zend_Controller_Router_Route_Regex('users/(\w+)/?(?:p/(\d+))?', null, array(1 => 'username', 2 => 'page'));
  134. $values = $route->match('users/martel');
  135. $this->assertSame(1, count($values));
  136. $this->assertSame('martel', $values['username']);
  137. }
  138. public function testMixedMap()
  139. {
  140. $route = new Zend_Controller_Router_Route_Regex('users/(\w+)/?(?:p/(\d+))?', null, array(1 => 'username'));
  141. $values = $route->match('users/martel/p/1');
  142. $this->assertSame(2, count($values));
  143. $this->assertSame('martel', $values['username']);
  144. $this->assertSame('1', $values[2]);
  145. }
  146. public function testNumericDefaultWithMap()
  147. {
  148. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array(1 => 'martel'), array(1 => 'username'));
  149. $values = $route->match('users');
  150. $this->assertSame(1, count($values));
  151. $this->assertSame('martel', $values['username']);
  152. }
  153. public function testMixedMapWithDefault()
  154. {
  155. $route = new Zend_Controller_Router_Route_Regex('users/(\w+)/?(?:p/(\d+))?', array(2 => '1'), array(1 => 'username'));
  156. $values = $route->match('users/martel/p/10');
  157. $this->assertSame(2, count($values));
  158. $this->assertSame('martel', $values['username']);
  159. $this->assertSame('10', $values[2]);
  160. }
  161. public function testMixedMapWithDefaults2()
  162. {
  163. $route = new Zend_Controller_Router_Route_Regex('users/?(\w+)?/?(?:p/(\d+))?', array(2 => '1', 'username' => 'martel'), array(1 => 'username'));
  164. $values = $route->match('users');
  165. $this->assertSame(2, count($values));
  166. $this->assertSame('martel', $values['username']);
  167. $this->assertSame('1', $values[2]);
  168. }
  169. public function testOptionalVarWithMapAndDefault()
  170. {
  171. $route = new Zend_Controller_Router_Route_Regex('users/(\w+)/?(?:p/(\d+))?', array('page' => '1', 'username' => 'martel'), array(1 => 'username', 2 => 'page'));
  172. $values = $route->match('users/martel');
  173. $this->assertSame(2, count($values));
  174. $this->assertSame('martel', $values['username']);
  175. $this->assertSame('1', $values['page']);
  176. }
  177. public function testOptionalVarWithMapAndNumericDefault()
  178. {
  179. $route = new Zend_Controller_Router_Route_Regex('users/(\w+)/?(?:p/(\d+))?', array(2 => '1'), array(2 => 'page'));
  180. $values = $route->match('users/martel');
  181. $this->assertSame(2, count($values));
  182. $this->assertSame('martel', $values[1]);
  183. $this->assertSame('1', $values['page']);
  184. }
  185. public function testMappedAndNumericDefault()
  186. {
  187. $route = new Zend_Controller_Router_Route_Regex('users/?(\w+)?', array(1 => 'martel', 'username' => 'vicki'), array(1 => 'username'));
  188. $values = $route->match('users');
  189. // Matches both defaults but the one defined last is used
  190. $this->assertSame(1, count($values));
  191. $this->assertSame('vicki', $values['username']);
  192. }
  193. public function testAssemble()
  194. {
  195. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, array(1 => 'username'), 'users/%s');
  196. $values = $route->match('users/martel');
  197. $url = $route->assemble();
  198. $this->assertSame('users/martel', $url);
  199. }
  200. public function testAssembleWithDefault()
  201. {
  202. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array(1 => 'martel'), null, 'users/%s');
  203. $values = $route->match('users');
  204. $url = $route->assemble();
  205. $this->assertSame('users/martel', $url);
  206. }
  207. public function testAssembleWithMappedDefault()
  208. {
  209. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array('username' => 'martel'), array(1 => 'username'), 'users/%s');
  210. $values = $route->match('users');
  211. $url = $route->assemble();
  212. $this->assertSame('users/martel', $url);
  213. }
  214. public function testAssembleWithData()
  215. {
  216. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, null, 'users/%s');
  217. $values = $route->match('users/martel');
  218. $url = $route->assemble(array(1 => 'vicki'));
  219. $this->assertSame('users/vicki', $url);
  220. }
  221. public function testAssembleWithMappedVariable()
  222. {
  223. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, array(1 => 'username'), 'users/%s');
  224. $values = $route->match('users/martel');
  225. $url = $route->assemble(array('username' => 'vicki'));
  226. $this->assertSame('users/vicki', $url);
  227. }
  228. public function testAssembleWithMappedVariableAndNumericKey()
  229. {
  230. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, array(1 => 'username'), 'users/%s');
  231. $values = $route->match('users/martel');
  232. $url = $route->assemble(array(1 => 'vicki'));
  233. $this->assertSame('users/vicki', $url);
  234. }
  235. public function testAssembleWithoutMatch()
  236. {
  237. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, null, 'users/%s');
  238. try {
  239. $url = $route->assemble();
  240. $this->fail();
  241. } catch (Exception $e) {}
  242. }
  243. public function testAssembleWithDefaultWithoutMatch()
  244. {
  245. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array(1 => 'martel'), null, 'users/%s');
  246. $url = $route->assemble();
  247. $this->assertSame('users/martel', $url);
  248. }
  249. public function testAssembleWithMappedDefaultWithoutMatch()
  250. {
  251. $route = new Zend_Controller_Router_Route_Regex('users/?(.+)?', array('username' => 'martel'), array(1 => 'username'), 'users/%s');
  252. $url = $route->assemble();
  253. $this->assertSame('users/martel', $url);
  254. }
  255. public function testAssembleWithDataWithoutMatch()
  256. {
  257. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, null, 'users/%s');
  258. $url = $route->assemble(array(1 => 'vicki'));
  259. $this->assertSame('users/vicki', $url);
  260. }
  261. public function testAssembleWithMappedVariableWithoutMatch()
  262. {
  263. $route = new Zend_Controller_Router_Route_Regex('users/(.+)', null, array(1 => 'username'), 'users/%s');
  264. $url = $route->assemble(array('username' => 'vicki'));
  265. $this->assertSame('users/vicki', $url);
  266. }
  267. public function testAssembleZF1332()
  268. {
  269. $route = new Zend_Controller_Router_Route_Regex(
  270. '(.+)\.([0-9]+)-([0-9]+)\.html',
  271. array('module' => 'default', 'controller' => 'content.item', 'action' => 'forward'),
  272. array(1 => 'name', 2 => 'id', 3 => 'class'),
  273. '%s.%s-%s.html'
  274. );
  275. $route->match('uml-explained-composition.72-3.html');
  276. $url = $route->assemble();
  277. $this->assertSame('uml-explained-composition.72-3.html', $url);
  278. $url = $route->assemble(array('name' => 'post_name', 'id' => '12', 'class' => 5));
  279. $this->assertSame('post_name.12-5.html', $url);
  280. }
  281. public function testGetInstance()
  282. {
  283. require_once 'Zend/Config.php';
  284. $routeConf = array(
  285. 'route' => 'forum/(\d+)',
  286. 'reverse' => 'forum/%d',
  287. 'defaults' => array(
  288. 'controller' => 'ctrl'
  289. )
  290. );
  291. /* numeric Zend_Config indexes don't work at the moment
  292. 'map' => array(
  293. '1' => 'forum_id'
  294. )
  295. */
  296. $config = new Zend_Config($routeConf);
  297. $route = Zend_Controller_Router_Route_Regex::getInstance($config);
  298. $this->assertType('Zend_Controller_Router_Route_Regex', $route);
  299. $values = $route->match('forum/1');
  300. $this->assertSame('ctrl', $values['controller']);
  301. }
  302. /**
  303. * @issue ZF-2301
  304. */
  305. public function testAssemblyOfRouteWithMergedMatchedParts()
  306. {
  307. $route = new Zend_Controller_Router_Route_Regex(
  308. 'itemlist(?:/(\d+))?',
  309. array('page' => 1), // Defaults
  310. array(1 => 'page'), // Parameter map
  311. 'itemlist/%d'
  312. );
  313. // make sure defaults work
  314. $this->assertEquals(array('page' => 1), $route->match('/itemlist/'));
  315. // make sure default assembly work
  316. $this->assertEquals('itemlist/1', $route->assemble());
  317. // make sure the route is parsed correctly
  318. $this->assertEquals(array('page' => 2), $route->match('/itemlist/2'));
  319. // check to make sure that the default assembly will return with default 1 (previously defined)
  320. $this->assertEquals('itemlist/2', $route->assemble());
  321. // check to make sure that the assembly will return with provided page=3 in the correct place
  322. $this->assertEquals('itemlist/3', $route->assemble(array('page' => 3)));
  323. // check to make sure that the assembly can reset a single parameter
  324. $this->assertEquals('itemlist/1', $route->assemble(array('page' => null)));
  325. }
  326. /**
  327. * @group ZF-4335
  328. */
  329. public function testAssembleMethodShouldNotIgnoreEncodeParam()
  330. {
  331. $route = new Zend_Controller_Router_Route_Regex(
  332. 'blog/archive/(.+)-(.+)\.html',
  333. array(
  334. 'controller' => 'blog',
  335. 'action' => 'view'
  336. ),
  337. array(
  338. 1 => 'name',
  339. 2 => 'description'
  340. ),
  341. 'blog/archive/%s-%s.html'
  342. );
  343. $data = array('string.that&has=some>', 'characters<that;need+to$be*encoded');
  344. $url = $route->assemble($data, false, true);
  345. $expectedUrl = 'blog/archive/string.that%26has%3Dsome%3E-characters%3Cthat%3Bneed%2Bto%24be%2Aencoded.html';
  346. $this->assertEquals($url, $expectedUrl, 'Assembled url isn\'t encoded properly when using the encode parameter.');
  347. }
  348. }