]>
Commit | Line | Data |
---|---|---|
4f5b44bd NL |
1 | <?php |
2 | ||
3 | /* | |
4 | * This file is part of the Symfony package. | |
5 | * | |
6 | * (c) Fabien Potencier <fabien@symfony.com> | |
7 | * | |
8 | * For the full copyright and license information, please view the LICENSE | |
9 | * file that was distributed with this source code. | |
10 | */ | |
11 | ||
12 | namespace Symfony\Component\Routing\Tests; | |
13 | ||
14 | use Symfony\Component\Routing\Route; | |
15 | ||
16 | class RouteCompilerTest extends \PHPUnit_Framework_TestCase | |
17 | { | |
18 | /** | |
19 | * @dataProvider provideCompileData | |
20 | */ | |
21 | public function testCompile($name, $arguments, $prefix, $regex, $variables, $tokens) | |
22 | { | |
23 | $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route'); | |
24 | $route = $r->newInstanceArgs($arguments); | |
25 | ||
26 | $compiled = $route->compile(); | |
27 | $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)'); | |
28 | $this->assertEquals($regex, $compiled->getRegex(), $name.' (regex)'); | |
29 | $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)'); | |
30 | $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)'); | |
31 | } | |
32 | ||
33 | public function provideCompileData() | |
34 | { | |
35 | return array( | |
36 | array( | |
37 | 'Static route', | |
38 | array('/foo'), | |
39 | '/foo', '#^/foo$#s', array(), array( | |
40 | array('text', '/foo'), | |
41 | )), | |
42 | ||
43 | array( | |
44 | 'Route with a variable', | |
45 | array('/foo/{bar}'), | |
46 | '/foo', '#^/foo/(?P<bar>[^/]++)$#s', array('bar'), array( | |
47 | array('variable', '/', '[^/]++', 'bar'), | |
48 | array('text', '/foo'), | |
49 | )), | |
50 | ||
51 | array( | |
52 | 'Route with a variable that has a default value', | |
53 | array('/foo/{bar}', array('bar' => 'bar')), | |
54 | '/foo', '#^/foo(?:/(?P<bar>[^/]++))?$#s', array('bar'), array( | |
55 | array('variable', '/', '[^/]++', 'bar'), | |
56 | array('text', '/foo'), | |
57 | )), | |
58 | ||
59 | array( | |
60 | 'Route with several variables', | |
61 | array('/foo/{bar}/{foobar}'), | |
62 | '/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#s', array('bar', 'foobar'), array( | |
63 | array('variable', '/', '[^/]++', 'foobar'), | |
64 | array('variable', '/', '[^/]++', 'bar'), | |
65 | array('text', '/foo'), | |
66 | )), | |
67 | ||
68 | array( | |
69 | 'Route with several variables that have default values', | |
70 | array('/foo/{bar}/{foobar}', array('bar' => 'bar', 'foobar' => '')), | |
71 | '/foo', '#^/foo(?:/(?P<bar>[^/]++)(?:/(?P<foobar>[^/]++))?)?$#s', array('bar', 'foobar'), array( | |
72 | array('variable', '/', '[^/]++', 'foobar'), | |
73 | array('variable', '/', '[^/]++', 'bar'), | |
74 | array('text', '/foo'), | |
75 | )), | |
76 | ||
77 | array( | |
78 | 'Route with several variables but some of them have no default values', | |
79 | array('/foo/{bar}/{foobar}', array('bar' => 'bar')), | |
80 | '/foo', '#^/foo/(?P<bar>[^/]++)/(?P<foobar>[^/]++)$#s', array('bar', 'foobar'), array( | |
81 | array('variable', '/', '[^/]++', 'foobar'), | |
82 | array('variable', '/', '[^/]++', 'bar'), | |
83 | array('text', '/foo'), | |
84 | )), | |
85 | ||
86 | array( | |
87 | 'Route with an optional variable as the first segment', | |
88 | array('/{bar}', array('bar' => 'bar')), | |
89 | '', '#^/(?P<bar>[^/]++)?$#s', array('bar'), array( | |
90 | array('variable', '/', '[^/]++', 'bar'), | |
91 | )), | |
92 | ||
93 | array( | |
94 | 'Route with a requirement of 0', | |
95 | array('/{bar}', array('bar' => null), array('bar' => '0')), | |
96 | '', '#^/(?P<bar>0)?$#s', array('bar'), array( | |
97 | array('variable', '/', '0', 'bar'), | |
98 | )), | |
99 | ||
100 | array( | |
101 | 'Route with an optional variable as the first segment with requirements', | |
102 | array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')), | |
103 | '', '#^/(?P<bar>(foo|bar))?$#s', array('bar'), array( | |
104 | array('variable', '/', '(foo|bar)', 'bar'), | |
105 | )), | |
106 | ||
107 | array( | |
108 | 'Route with only optional variables', | |
109 | array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')), | |
110 | '', '#^/(?P<foo>[^/]++)?(?:/(?P<bar>[^/]++))?$#s', array('foo', 'bar'), array( | |
111 | array('variable', '/', '[^/]++', 'bar'), | |
112 | array('variable', '/', '[^/]++', 'foo'), | |
113 | )), | |
114 | ||
115 | array( | |
116 | 'Route with a variable in last position', | |
117 | array('/foo-{bar}'), | |
118 | '/foo', '#^/foo\-(?P<bar>[^/]++)$#s', array('bar'), array( | |
119 | array('variable', '-', '[^/]++', 'bar'), | |
120 | array('text', '/foo'), | |
121 | )), | |
122 | ||
123 | array( | |
124 | 'Route with nested placeholders', | |
125 | array('/{static{var}static}'), | |
126 | '/{static', '#^/\{static(?P<var>[^/]+)static\}$#s', array('var'), array( | |
127 | array('text', 'static}'), | |
128 | array('variable', '', '[^/]+', 'var'), | |
129 | array('text', '/{static'), | |
130 | )), | |
131 | ||
132 | array( | |
133 | 'Route without separator between variables', | |
134 | array('/{w}{x}{y}{z}.{_format}', array('z' => 'default-z', '_format' => 'html'), array('y' => '(y|Y)')), | |
135 | '', '#^/(?P<w>[^/\.]+)(?P<x>[^/\.]+)(?P<y>(y|Y))(?:(?P<z>[^/\.]++)(?:\.(?P<_format>[^/]++))?)?$#s', array('w', 'x', 'y', 'z', '_format'), array( | |
136 | array('variable', '.', '[^/]++', '_format'), | |
137 | array('variable', '', '[^/\.]++', 'z'), | |
138 | array('variable', '', '(y|Y)', 'y'), | |
139 | array('variable', '', '[^/\.]+', 'x'), | |
140 | array('variable', '/', '[^/\.]+', 'w'), | |
141 | )), | |
142 | ||
143 | array( | |
144 | 'Route with a format', | |
145 | array('/foo/{bar}.{_format}'), | |
146 | '/foo', '#^/foo/(?P<bar>[^/\.]++)\.(?P<_format>[^/]++)$#s', array('bar', '_format'), array( | |
147 | array('variable', '.', '[^/]++', '_format'), | |
148 | array('variable', '/', '[^/\.]++', 'bar'), | |
149 | array('text', '/foo'), | |
150 | )), | |
151 | ); | |
152 | } | |
153 | ||
154 | /** | |
155 | * @expectedException \LogicException | |
156 | */ | |
157 | public function testRouteWithSameVariableTwice() | |
158 | { | |
159 | $route = new Route('/{name}/{name}'); | |
160 | ||
161 | $compiled = $route->compile(); | |
162 | } | |
163 | ||
164 | /** | |
165 | * @dataProvider getNumericVariableNames | |
166 | * @expectedException \DomainException | |
167 | */ | |
168 | public function testRouteWithNumericVariableName($name) | |
169 | { | |
170 | $route = new Route('/{'. $name.'}'); | |
171 | $route->compile(); | |
172 | } | |
173 | ||
174 | public function getNumericVariableNames() | |
175 | { | |
176 | return array( | |
177 | array('09'), | |
178 | array('123'), | |
179 | array('1e2') | |
180 | ); | |
181 | } | |
182 | ||
183 | /** | |
184 | * @dataProvider provideCompileWithHostData | |
185 | */ | |
186 | public function testCompileWithHost($name, $arguments, $prefix, $regex, $variables, $pathVariables, $tokens, $hostRegex, $hostVariables, $hostTokens) | |
187 | { | |
188 | $r = new \ReflectionClass('Symfony\\Component\\Routing\\Route'); | |
189 | $route = $r->newInstanceArgs($arguments); | |
190 | ||
191 | $compiled = $route->compile(); | |
192 | $this->assertEquals($prefix, $compiled->getStaticPrefix(), $name.' (static prefix)'); | |
193 | $this->assertEquals($regex, str_replace(array("\n", ' '), '', $compiled->getRegex()), $name.' (regex)'); | |
194 | $this->assertEquals($variables, $compiled->getVariables(), $name.' (variables)'); | |
195 | $this->assertEquals($pathVariables, $compiled->getPathVariables(), $name.' (path variables)'); | |
196 | $this->assertEquals($tokens, $compiled->getTokens(), $name.' (tokens)'); | |
197 | $this->assertEquals($hostRegex, str_replace(array("\n", ' '), '', $compiled->getHostRegex()), $name.' (host regex)'); | |
198 | $this->assertEquals($hostVariables, $compiled->getHostVariables(), $name.' (host variables)'); | |
199 | $this->assertEquals($hostTokens, $compiled->getHostTokens(), $name.' (host tokens)'); | |
200 | } | |
201 | ||
202 | public function provideCompileWithHostData() | |
203 | { | |
204 | return array( | |
205 | array( | |
206 | 'Route with host pattern', | |
207 | array('/hello', array(), array(), array(), 'www.example.com'), | |
208 | '/hello', '#^/hello$#s', array(), array(), array( | |
209 | array('text', '/hello'), | |
210 | ), | |
211 | '#^www\.example\.com$#s', array(), array( | |
212 | array('text', 'www.example.com'), | |
213 | ), | |
214 | ), | |
215 | array( | |
216 | 'Route with host pattern and some variables', | |
217 | array('/hello/{name}', array(), array(), array(), 'www.example.{tld}'), | |
218 | '/hello', '#^/hello/(?P<name>[^/]++)$#s', array('tld', 'name'), array('name'), array( | |
219 | array('variable', '/', '[^/]++', 'name'), | |
220 | array('text', '/hello'), | |
221 | ), | |
222 | '#^www\.example\.(?P<tld>[^\.]++)$#s', array('tld'), array( | |
223 | array('variable', '.', '[^\.]++', 'tld'), | |
224 | array('text', 'www.example'), | |
225 | ), | |
226 | ), | |
227 | array( | |
228 | 'Route with variable at beginning of host', | |
229 | array('/hello', array(), array(), array(), '{locale}.example.{tld}'), | |
230 | '/hello', '#^/hello$#s', array('locale', 'tld'), array(), array( | |
231 | array('text', '/hello'), | |
232 | ), | |
233 | '#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#s', array('locale', 'tld'), array( | |
234 | array('variable', '.', '[^\.]++', 'tld'), | |
235 | array('text', '.example'), | |
236 | array('variable', '', '[^\.]++', 'locale'), | |
237 | ), | |
238 | ), | |
239 | array( | |
240 | 'Route with host variables that has a default value', | |
241 | array('/hello', array('locale' => 'a', 'tld' => 'b'), array(), array(), '{locale}.example.{tld}'), | |
242 | '/hello', '#^/hello$#s', array('locale', 'tld'), array(), array( | |
243 | array('text', '/hello'), | |
244 | ), | |
245 | '#^(?P<locale>[^\.]++)\.example\.(?P<tld>[^\.]++)$#s', array('locale', 'tld'), array( | |
246 | array('variable', '.', '[^\.]++', 'tld'), | |
247 | array('text', '.example'), | |
248 | array('variable', '', '[^\.]++', 'locale'), | |
249 | ), | |
250 | ), | |
251 | ); | |
252 | } | |
253 | } |