actionpack 2.1.2 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (200) hide show
  1. data/CHANGELOG +223 -7
  2. data/README +6 -12
  3. data/Rakefile +11 -11
  4. data/lib/action_controller.rb +9 -9
  5. data/lib/action_controller/assertions/response_assertions.rb +29 -78
  6. data/lib/action_controller/assertions/routing_assertions.rb +33 -33
  7. data/lib/action_controller/assertions/selector_assertions.rb +9 -5
  8. data/lib/action_controller/base.rb +227 -161
  9. data/lib/action_controller/benchmarking.rb +37 -24
  10. data/lib/action_controller/caching/actions.rb +53 -21
  11. data/lib/action_controller/caching/fragments.rb +10 -36
  12. data/lib/action_controller/caching/sweeping.rb +3 -3
  13. data/lib/action_controller/cgi_ext/session.rb +2 -22
  14. data/lib/action_controller/cgi_process.rb +8 -46
  15. data/lib/action_controller/components.rb +4 -1
  16. data/lib/action_controller/cookies.rb +10 -0
  17. data/lib/action_controller/dispatcher.rb +49 -15
  18. data/lib/action_controller/filters.rb +48 -10
  19. data/lib/action_controller/headers.rb +16 -14
  20. data/lib/action_controller/helpers.rb +2 -2
  21. data/lib/action_controller/http_authentication.rb +1 -1
  22. data/lib/action_controller/integration.rb +57 -60
  23. data/lib/action_controller/layout.rb +27 -53
  24. data/lib/action_controller/mime_responds.rb +5 -1
  25. data/lib/action_controller/mime_type.rb +64 -42
  26. data/lib/action_controller/mime_types.rb +2 -1
  27. data/lib/action_controller/performance_test.rb +16 -0
  28. data/lib/action_controller/polymorphic_routes.rb +16 -9
  29. data/lib/action_controller/rack_process.rb +303 -0
  30. data/lib/action_controller/request.rb +205 -97
  31. data/lib/action_controller/request_forgery_protection.rb +2 -2
  32. data/lib/action_controller/request_profiler.rb +0 -0
  33. data/lib/action_controller/rescue.rb +20 -115
  34. data/lib/action_controller/resources.rb +186 -83
  35. data/lib/action_controller/response.rb +140 -26
  36. data/lib/action_controller/routing.rb +28 -30
  37. data/lib/action_controller/routing/builder.rb +45 -54
  38. data/lib/action_controller/routing/optimisations.rb +31 -21
  39. data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
  40. data/lib/action_controller/routing/route.rb +162 -147
  41. data/lib/action_controller/routing/route_set.rb +8 -7
  42. data/lib/action_controller/routing/routing_ext.rb +4 -1
  43. data/lib/action_controller/routing/segments.rb +50 -21
  44. data/lib/action_controller/session/cookie_store.rb +3 -2
  45. data/lib/action_controller/session/drb_server.rb +7 -7
  46. data/lib/action_controller/session_management.rb +6 -2
  47. data/lib/action_controller/streaming.rb +15 -8
  48. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  49. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  50. data/lib/action_controller/test_case.rb +66 -2
  51. data/lib/action_controller/test_process.rb +71 -66
  52. data/lib/action_controller/translation.rb +13 -0
  53. data/lib/action_controller/url_rewriter.rb +90 -13
  54. data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
  55. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
  56. data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
  57. data/lib/action_controller/verification.rb +2 -2
  58. data/lib/action_pack/version.rb +1 -1
  59. data/lib/action_view.rb +19 -11
  60. data/lib/action_view/base.rb +184 -150
  61. data/lib/action_view/helpers.rb +38 -0
  62. data/lib/action_view/helpers/active_record_helper.rb +56 -27
  63. data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
  64. data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
  65. data/lib/action_view/helpers/benchmark_helper.rb +3 -3
  66. data/lib/action_view/helpers/cache_helper.rb +1 -2
  67. data/lib/action_view/helpers/capture_helper.rb +19 -44
  68. data/lib/action_view/helpers/date_helper.rb +486 -296
  69. data/lib/action_view/helpers/debug_helper.rb +20 -13
  70. data/lib/action_view/helpers/form_helper.rb +71 -30
  71. data/lib/action_view/helpers/form_options_helper.rb +15 -85
  72. data/lib/action_view/helpers/form_tag_helper.rb +61 -38
  73. data/lib/action_view/helpers/javascript_helper.rb +80 -89
  74. data/lib/action_view/helpers/number_helper.rb +179 -74
  75. data/lib/action_view/helpers/prototype_helper.rb +216 -201
  76. data/lib/action_view/helpers/record_tag_helper.rb +4 -5
  77. data/lib/action_view/helpers/sanitize_helper.rb +65 -33
  78. data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
  79. data/lib/action_view/helpers/tag_helper.rb +39 -22
  80. data/lib/action_view/helpers/text_helper.rb +212 -118
  81. data/lib/action_view/helpers/translation_helper.rb +21 -0
  82. data/lib/action_view/helpers/url_helper.rb +100 -58
  83. data/lib/action_view/inline_template.rb +13 -14
  84. data/lib/action_view/locale/en.yml +91 -0
  85. data/lib/action_view/partials.rb +100 -55
  86. data/lib/action_view/paths.rb +125 -0
  87. data/lib/action_view/renderable.rb +102 -0
  88. data/lib/action_view/renderable_partial.rb +48 -0
  89. data/lib/action_view/template.rb +90 -101
  90. data/lib/action_view/template_error.rb +11 -21
  91. data/lib/action_view/template_handler.rb +8 -28
  92. data/lib/action_view/template_handlers.rb +45 -0
  93. data/lib/action_view/template_handlers/builder.rb +5 -15
  94. data/lib/action_view/template_handlers/erb.rb +9 -6
  95. data/lib/action_view/template_handlers/rjs.rb +2 -17
  96. data/lib/action_view/test_case.rb +7 -4
  97. data/test/abstract_unit.rb +4 -1
  98. data/test/active_record_unit.rb +28 -30
  99. data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
  100. data/test/controller/action_pack_assertions_test.rb +8 -37
  101. data/test/controller/addresses_render_test.rb +0 -3
  102. data/test/controller/assert_select_test.rb +51 -24
  103. data/test/controller/base_test.rb +4 -4
  104. data/test/controller/caching_test.rb +136 -66
  105. data/test/controller/capture_test.rb +1 -21
  106. data/test/controller/cgi_test.rb +157 -10
  107. data/test/controller/components_test.rb +41 -25
  108. data/test/controller/content_type_test.rb +49 -17
  109. data/test/controller/cookie_test.rb +1 -1
  110. data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
  111. data/test/controller/dispatcher_test.rb +9 -1
  112. data/test/controller/filter_params_test.rb +2 -2
  113. data/test/controller/filters_test.rb +13 -13
  114. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  115. data/test/controller/html-scanner/node_test.rb +21 -0
  116. data/test/controller/html-scanner/sanitizer_test.rb +14 -0
  117. data/test/controller/integration_test.rb +167 -6
  118. data/test/controller/layout_test.rb +11 -68
  119. data/test/controller/logging_test.rb +46 -0
  120. data/test/controller/mime_responds_test.rb +61 -59
  121. data/test/controller/mime_type_test.rb +6 -6
  122. data/test/controller/polymorphic_routes_test.rb +37 -2
  123. data/test/controller/rack_test.rb +323 -0
  124. data/test/controller/redirect_test.rb +72 -71
  125. data/test/controller/render_test.rb +1120 -108
  126. data/test/controller/request_forgery_protection_test.rb +66 -52
  127. data/test/controller/request_test.rb +103 -146
  128. data/test/controller/rescue_test.rb +20 -24
  129. data/test/controller/resources_test.rb +408 -25
  130. data/test/controller/routing_test.rb +1774 -1774
  131. data/test/controller/send_file_test.rb +0 -4
  132. data/test/controller/session/cookie_store_test.rb +53 -1
  133. data/test/controller/test_test.rb +15 -37
  134. data/test/controller/translation_test.rb +26 -0
  135. data/test/controller/url_rewriter_test.rb +27 -28
  136. data/test/controller/view_paths_test.rb +48 -47
  137. data/test/fixtures/_top_level_partial.html.erb +1 -0
  138. data/test/fixtures/_top_level_partial_only.erb +1 -0
  139. data/test/fixtures/developers/_developer.erb +1 -0
  140. data/test/fixtures/fun/games/_game.erb +1 -0
  141. data/test/fixtures/fun/serious/games/_game.erb +1 -0
  142. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
  143. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
  144. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
  145. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
  146. data/test/fixtures/layouts/_column.html.erb +2 -0
  147. data/test/fixtures/projects/_project.erb +1 -0
  148. data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
  149. data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
  150. data/test/fixtures/replies/_reply.erb +1 -0
  151. data/test/fixtures/test/_counter.html.erb +1 -0
  152. data/test/fixtures/test/_customer.erb +1 -1
  153. data/test/fixtures/test/_customer_with_var.erb +1 -0
  154. data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
  155. data/test/fixtures/test/_local_inspector.html.erb +1 -0
  156. data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
  157. data/test/fixtures/test/hello.builder +1 -1
  158. data/test/fixtures/test/hyphen-ated.erb +1 -0
  159. data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
  160. data/test/fixtures/test/nested_layout.erb +3 -0
  161. data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
  162. data/test/fixtures/test/sub_template_raise.html.erb +1 -0
  163. data/test/fixtures/test/template.erb +1 -0
  164. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
  165. data/test/template/active_record_helper_i18n_test.rb +46 -0
  166. data/test/template/active_record_helper_test.rb +24 -24
  167. data/test/template/asset_tag_helper_test.rb +161 -29
  168. data/test/template/atom_feed_helper_test.rb +114 -5
  169. data/test/template/compiled_templates_test.rb +59 -0
  170. data/test/template/date_helper_i18n_test.rb +113 -0
  171. data/test/template/date_helper_test.rb +403 -109
  172. data/test/template/form_helper_test.rb +213 -154
  173. data/test/template/form_options_helper_test.rb +249 -897
  174. data/test/template/form_tag_helper_test.rb +80 -32
  175. data/test/template/javascript_helper_test.rb +17 -18
  176. data/test/template/number_helper_i18n_test.rb +54 -0
  177. data/test/template/number_helper_test.rb +43 -13
  178. data/test/template/prototype_helper_test.rb +101 -84
  179. data/test/template/record_tag_helper_test.rb +24 -20
  180. data/test/template/render_test.rb +193 -0
  181. data/test/template/sanitize_helper_test.rb +3 -3
  182. data/test/template/tag_helper_test.rb +34 -14
  183. data/test/template/text_helper_test.rb +83 -9
  184. data/test/template/translation_helper_test.rb +28 -0
  185. data/test/template/url_helper_test.rb +55 -18
  186. metadata +57 -18
  187. data/lib/action_view/helpers/javascripts/controls.js +0 -963
  188. data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
  189. data/lib/action_view/helpers/javascripts/effects.js +0 -1120
  190. data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
  191. data/lib/action_view/partial_template.rb +0 -70
  192. data/lib/action_view/template_finder.rb +0 -177
  193. data/lib/action_view/template_handlers/compilable.rb +0 -128
  194. data/test/controller/custom_handler_test.rb +0 -45
  195. data/test/controller/new_render_test.rb +0 -945
  196. data/test/fixtures/test/block_content_for.erb +0 -2
  197. data/test/fixtures/test/erb_content_for.erb +0 -2
  198. data/test/template/deprecated_erb_variable_test.rb +0 -9
  199. data/test/template/template_finder_test.rb +0 -73
  200. data/test/template/template_object_test.rb +0 -95
@@ -59,838 +59,180 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase
59
59
  end
60
60
  end
61
61
 
62
- class LegacyRouteSetTests < Test::Unit::TestCase
63
- attr_reader :rs
64
- def setup
65
- # These tests assume optimisation is on, so re-enable it.
66
- ActionController::Base.optimise_named_routes = true
67
-
68
- @rs = ::ActionController::Routing::RouteSet.new
69
- @rs.draw {|m| m.connect ':controller/:action/:id' }
70
-
71
- ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed)
72
- end
73
-
74
- def test_default_setup
75
- assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
76
- assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
77
- assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
78
-
79
- assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
80
-
81
- assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10)
82
-
83
- assert_equal '/admin/user/show', rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
84
- assert_equal '/admin/user/list/10', rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'})
85
-
86
- assert_equal '/admin/stuff', rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
87
- assert_equal '/stuff', rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
88
- end
89
-
90
- def test_ignores_leading_slash
91
- @rs.draw {|m| m.connect '/:controller/:action/:id'}
92
- test_default_setup
93
- end
94
-
95
- def test_time_recognition
96
- # We create many routes to make situation more realistic
97
- @rs = ::ActionController::Routing::RouteSet.new
98
- @rs.draw { |map|
99
- map.frontpage '', :controller => 'search', :action => 'new'
100
- map.resources :videos do |video|
101
- video.resources :comments
102
- video.resource :file, :controller => 'video_file'
103
- video.resource :share, :controller => 'video_shares'
104
- video.resource :abuse, :controller => 'video_abuses'
105
- end
106
- map.resources :abuses, :controller => 'video_abuses'
107
- map.resources :video_uploads
108
- map.resources :video_visits
109
-
110
- map.resources :users do |user|
111
- user.resource :settings
112
- user.resources :videos
113
- end
114
- map.resources :channels do |channel|
115
- channel.resources :videos, :controller => 'channel_videos'
116
- end
117
- map.resource :session
118
- map.resource :lost_password
119
- map.search 'search', :controller => 'search'
120
- map.resources :pages
121
- map.connect ':controller/:action/:id'
122
- }
123
- n = 1000
124
- if RunTimeTests
125
- GC.start
126
- rectime = Benchmark.realtime do
127
- n.times do
128
- rs.recognize_path("/videos/1234567", {:method => :get})
129
- rs.recognize_path("/videos/1234567/abuse", {:method => :get})
130
- rs.recognize_path("/users/1234567/settings", {:method => :get})
131
- rs.recognize_path("/channels/1234567", {:method => :get})
132
- rs.recognize_path("/session/new", {:method => :get})
133
- rs.recognize_path("/admin/user/show/10", {:method => :get})
134
- end
135
- end
136
- puts "\n\nRecognition (#{rs.routes.size} routes):"
137
- per_url = rectime / (n * 6)
138
- puts "#{per_url * 1000} ms/url"
139
- puts "#{1 / per_url} url/s\n\n"
140
- end
141
- end
142
- def test_time_generation
143
- n = 5000
144
- if RunTimeTests
145
- GC.start
146
- pairs = [
147
- [{:controller => 'content', :action => 'index'}, {:controller => 'content', :action => 'show'}],
148
- [{:controller => 'content'}, {:controller => 'content', :action => 'index'}],
149
- [{:controller => 'content', :action => 'list'}, {:controller => 'content', :action => 'index'}],
150
- [{:controller => 'content', :action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}],
151
- [{:controller => 'admin/user', :action => 'index'}, {:controller => 'admin/user', :action => 'show'}],
152
- [{:controller => 'admin/user'}, {:controller => 'admin/user', :action => 'index'}],
153
- [{:controller => 'admin/user', :action => 'list'}, {:controller => 'admin/user', :action => 'index'}],
154
- [{:controller => 'admin/user', :action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}],
155
- ]
156
- p = nil
157
- gentime = Benchmark.realtime do
158
- n.times do
159
- pairs.each {|(a, b)| rs.generate(a, b)}
160
- end
161
- end
162
-
163
- puts "\n\nGeneration (RouteSet): (#{(n * 8)} urls)"
164
- per_url = gentime / (n * 8)
165
- puts "#{per_url * 1000} ms/url"
166
- puts "#{1 / per_url} url/s\n\n"
167
- end
168
- end
169
-
170
- def test_route_with_colon_first
171
- rs.draw do |map|
172
- map.connect '/:controller/:action/:id', :action => 'index', :id => nil
173
- map.connect ':url', :controller => 'tiny_url', :action => 'translate'
174
- end
175
- end
176
-
177
- def test_route_with_regexp_for_controller
178
- rs.draw do |map|
179
- map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/
180
- map.connect ':controller/:action/:id'
181
- end
182
- assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
183
- rs.recognize_path("/admin/user/foo"))
184
- assert_equal({:controller => "content", :action => "foo"}, rs.recognize_path("/content/foo"))
185
- assert_equal '/admin/user/foo', rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index")
186
- assert_equal '/content/foo', rs.generate(:controller => "content", :action => "foo")
187
- end
188
-
189
- def test_route_with_regexp_and_dot
190
- rs.draw do |map|
191
- map.connect ':controller/:action/:file',
192
- :controller => /admin|user/,
193
- :action => /upload|download/,
194
- :defaults => {:file => nil},
195
- :requirements => {:file => %r{[^/]+(\.[^/]+)?}}
196
- end
197
- # Without a file extension
198
- assert_equal '/user/download/file',
199
- rs.generate(:controller => "user", :action => "download", :file => "file")
200
- assert_equal(
201
- {:controller => "user", :action => "download", :file => "file"},
202
- rs.recognize_path("/user/download/file"))
203
-
204
- # Now, let's try a file with an extension, really a dot (.)
205
- assert_equal '/user/download/file.jpg',
206
- rs.generate(
207
- :controller => "user", :action => "download", :file => "file.jpg")
208
- assert_equal(
209
- {:controller => "user", :action => "download", :file => "file.jpg"},
210
- rs.recognize_path("/user/download/file.jpg"))
211
- end
212
-
213
- def test_basic_named_route
214
- rs.add_named_route :home, '', :controller => 'content', :action => 'list'
215
- x = setup_for_named_route
216
- assert_equal("http://named.route.test/",
217
- x.send(:home_url))
218
- end
219
-
220
- def test_basic_named_route_with_relative_url_root
221
- rs.add_named_route :home, '', :controller => 'content', :action => 'list'
222
- x = setup_for_named_route
223
- x.relative_url_root="/foo"
224
- assert_equal("http://named.route.test/foo/",
225
- x.send(:home_url))
226
- assert_equal "/foo/", x.send(:home_path)
227
- end
228
-
229
- def test_named_route_with_option
230
- rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page'
231
- x = setup_for_named_route
232
- assert_equal("http://named.route.test/page/new%20stuff",
233
- x.send(:page_url, :title => 'new stuff'))
234
- end
235
-
236
- def test_named_route_with_default
237
- rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage'
238
- x = setup_for_named_route
239
- assert_equal("http://named.route.test/page/AboutRails",
240
- x.send(:page_url, :title => "AboutRails"))
241
-
242
- end
243
-
244
- def test_named_route_with_nested_controller
245
- rs.add_named_route :users, 'admin/user', :controller => 'admin/user', :action => 'index'
246
- x = setup_for_named_route
247
- assert_equal("http://named.route.test/admin/user",
248
- x.send(:users_url))
249
- end
250
-
251
- uses_mocha "named route optimisation" do
252
- def test_optimised_named_route_call_never_uses_url_for
253
- rs.add_named_route :users, 'admin/user', :controller => '/admin/user', :action => 'index'
254
- rs.add_named_route :user, 'admin/user/:id', :controller=>'/admin/user', :action=>'show'
255
- x = setup_for_named_route
256
- x.expects(:url_for).never
257
- x.send(:users_url)
258
- x.send(:users_path)
259
- x.send(:user_url, 2, :foo=>"bar")
260
- x.send(:user_path, 3, :bar=>"foo")
261
- end
262
-
263
- def test_optimised_named_route_with_host
264
- rs.add_named_route :pages, 'pages', :controller => 'content', :action => 'show_page', :host => 'foo.com'
265
- x = setup_for_named_route
266
- x.expects(:url_for).with(:host => 'foo.com', :only_path => false, :controller => 'content', :action => 'show_page', :use_route => :pages).once
267
- x.send(:pages_url)
268
- end
269
- end
270
-
271
- def setup_for_named_route
272
- klass = Class.new(MockController)
273
- rs.install_helpers(klass)
274
- klass.new(rs)
275
- end
276
-
277
- def test_named_route_without_hash
278
- rs.draw do |map|
279
- map.normal ':controller/:action/:id'
280
- end
281
- end
282
-
283
- def test_named_route_root
284
- rs.draw do |map|
285
- map.root :controller => "hello"
286
- end
287
- x = setup_for_named_route
288
- assert_equal("http://named.route.test/", x.send(:root_url))
289
- assert_equal("/", x.send(:root_path))
290
- end
291
-
292
- def test_named_route_with_regexps
293
- rs.draw do |map|
294
- map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show',
295
- :year => /\d+/, :month => /\d+/, :day => /\d+/
296
- map.connect ':controller/:action/:id'
297
- end
298
- x = setup_for_named_route
299
- # assert_equal(
300
- # {:controller => 'page', :action => 'show', :title => 'hi', :use_route => :article, :only_path => false},
301
- # x.send(:article_url, :title => 'hi')
302
- # )
303
- assert_equal(
304
- "http://named.route.test/page/2005/6/10/hi",
305
- x.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
306
- )
307
- end
308
-
309
- def test_changing_controller
310
- assert_equal '/admin/stuff/show/10', rs.generate(
311
- {:controller => 'stuff', :action => 'show', :id => 10},
312
- {:controller => 'admin/user', :action => 'index'}
313
- )
314
- end
315
-
316
- def test_paths_escaped
317
- rs.draw do |map|
318
- map.path 'file/*path', :controller => 'content', :action => 'show_file'
319
- map.connect ':controller/:action/:id'
320
- end
321
-
322
- # No + to space in URI escaping, only for query params.
323
- results = rs.recognize_path "/file/hello+world/how+are+you%3F"
324
- assert results, "Recognition should have succeeded"
325
- assert_equal ['hello+world', 'how+are+you?'], results[:path]
326
-
327
- # Use %20 for space instead.
328
- results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F"
329
- assert results, "Recognition should have succeeded"
330
- assert_equal ['hello world', 'how are you?'], results[:path]
331
-
332
- results = rs.recognize_path "/file"
333
- assert results, "Recognition should have succeeded"
334
- assert_equal [], results[:path]
335
- end
336
-
337
- def test_paths_slashes_unescaped_with_ordered_parameters
338
- rs.add_named_route :path, '/file/*path', :controller => 'content'
339
-
340
- # No / to %2F in URI, only for query params.
341
- x = setup_for_named_route
342
- assert_equal("/file/hello/world", x.send(:path_path, 'hello/world'))
343
- end
344
-
345
- def test_non_controllers_cannot_be_matched
346
- rs.draw do |map|
347
- map.connect ':controller/:action/:id'
348
- end
349
- assert_raises(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
350
- end
351
-
352
- def test_paths_do_not_accept_defaults
353
- assert_raises(ActionController::RoutingError) do
354
- rs.draw do |map|
355
- map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default)
356
- map.connect ':controller/:action/:id'
357
- end
358
- end
359
-
360
- rs.draw do |map|
361
- map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => []
362
- map.connect ':controller/:action/:id'
363
- end
364
- end
365
-
366
- def test_should_list_options_diff_when_routing_requirements_dont_match
367
- rs.draw do |map|
368
- map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
369
- end
370
- exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") }
371
- assert_match /^post_url failed to generate/, exception.message
372
- from_match = exception.message.match(/from \{[^\}]+\}/).to_s
373
- assert_match /:bad_param=>"foo"/, from_match
374
- assert_match /:action=>"show"/, from_match
375
- assert_match /:controller=>"post"/, from_match
376
-
377
- expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s
378
- assert_no_match /:bad_param=>"foo"/, expected_match
379
- assert_match /:action=>"show"/, expected_match
380
- assert_match /:controller=>"post"/, expected_match
381
-
382
- diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s
383
- assert_match /:bad_param=>"foo"/, diff_match
384
- assert_no_match /:action=>"show"/, diff_match
385
- assert_no_match /:controller=>"post"/, diff_match
386
- end
387
-
388
- # this specifies the case where your formerly would get a very confusing error message with an empty diff
389
- def test_should_have_better_error_message_when_options_diff_is_empty
390
- rs.draw do |map|
391
- map.content '/content/:query', :controller => 'content', :action => 'show'
392
- end
393
-
394
- exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") }
395
- assert_match %r[:action=>"show"], exception.message
396
- assert_match %r[:controller=>"content"], exception.message
397
- assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message
398
- assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message
399
- end
400
-
401
- def test_dynamic_path_allowed
402
- rs.draw do |map|
403
- map.connect '*path', :controller => 'content', :action => 'show_file'
404
- end
405
-
406
- assert_equal '/pages/boo', rs.generate(:controller => 'content', :action => 'show_file', :path => %w(pages boo))
407
- end
408
-
409
- def test_dynamic_recall_paths_allowed
410
- rs.draw do |map|
411
- map.connect '*path', :controller => 'content', :action => 'show_file'
412
- end
413
-
414
- recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo))
415
- assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path)
416
- end
417
-
418
- def test_backwards
419
- rs.draw do |map|
420
- map.connect 'page/:id/:action', :controller => 'pages', :action => 'show'
421
- map.connect ':controller/:action/:id'
422
- end
423
-
424
- assert_equal '/page/20', rs.generate({:id => 20}, {:controller => 'pages', :action => 'show'})
425
- assert_equal '/page/20', rs.generate(:controller => 'pages', :id => 20, :action => 'show')
426
- assert_equal '/pages/boo', rs.generate(:controller => 'pages', :action => 'boo')
427
- end
428
-
429
- def test_route_with_fixnum_default
430
- rs.draw do |map|
431
- map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
432
- map.connect ':controller/:action/:id'
433
- end
434
-
435
- assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page')
436
- assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => 1)
437
- assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => '1')
438
- assert_equal '/page/10', rs.generate(:controller => 'content', :action => 'show_page', :id => 10)
439
-
440
- assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page"))
441
- assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
442
- assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
443
- end
444
-
445
- # For newer revision
446
- def test_route_with_text_default
447
- rs.draw do |map|
448
- map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
449
- map.connect ':controller/:action/:id'
450
- end
451
-
452
- assert_equal '/page/foo', rs.generate(:controller => 'content', :action => 'show_page', :id => 'foo')
453
- assert_equal({:controller => "content", :action => 'show_page', :id => 'foo'}, rs.recognize_path("/page/foo"))
454
-
455
- token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in russian
456
- escaped_token = CGI::escape(token)
457
-
458
- assert_equal '/page/' + escaped_token, rs.generate(:controller => 'content', :action => 'show_page', :id => token)
459
- assert_equal({:controller => "content", :action => 'show_page', :id => token}, rs.recognize_path("/page/#{escaped_token}"))
460
- end
461
-
462
- def test_action_expiry
463
- assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
464
- end
465
-
466
- def test_recognition_with_uppercase_controller_name
467
- assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content"))
468
- assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list"))
469
- assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10"))
470
-
471
- # these used to work, before the routes rewrite, but support for this was pulled in the new version...
472
- #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed"))
473
- #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed"))
474
- end
475
-
476
- def test_requirement_should_prevent_optional_id
477
- rs.draw do |map|
478
- map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
479
- end
480
-
481
- assert_equal '/post/10', rs.generate(:controller => 'post', :action => 'show', :id => 10)
482
-
483
- assert_raises ActionController::RoutingError do
484
- rs.generate(:controller => 'post', :action => 'show')
485
- end
486
- end
487
-
488
- def test_both_requirement_and_optional
489
- rs.draw do |map|
490
- map.blog('test/:year', :controller => 'post', :action => 'show',
491
- :defaults => { :year => nil },
492
- :requirements => { :year => /\d{4}/ }
493
- )
494
- map.connect ':controller/:action/:id'
495
- end
496
-
497
- assert_equal '/test', rs.generate(:controller => 'post', :action => 'show')
498
- assert_equal '/test', rs.generate(:controller => 'post', :action => 'show', :year => nil)
499
-
500
- x = setup_for_named_route
501
- assert_equal("http://named.route.test/test",
502
- x.send(:blog_url))
503
- end
504
-
505
- def test_set_to_nil_forgets
506
- rs.draw do |map|
507
- map.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil
508
- map.connect ':controller/:action/:id'
509
- end
510
-
511
- assert_equal '/pages/2005',
512
- rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005)
513
- assert_equal '/pages/2005/6',
514
- rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6)
515
- assert_equal '/pages/2005/6/12',
516
- rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12)
517
-
518
- assert_equal '/pages/2005/6/4',
519
- rs.generate({:day => 4}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
520
-
521
- assert_equal '/pages/2005/6',
522
- rs.generate({:day => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
523
-
524
- assert_equal '/pages/2005',
525
- rs.generate({:day => nil, :month => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
526
- end
527
-
528
- def test_url_with_no_action_specified
529
- rs.draw do |map|
530
- map.connect '', :controller => 'content'
531
- map.connect ':controller/:action/:id'
532
- end
533
-
534
- assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
535
- assert_equal '/', rs.generate(:controller => 'content')
536
- end
537
-
538
- def test_named_url_with_no_action_specified
539
- rs.draw do |map|
540
- map.home '', :controller => 'content'
541
- map.connect ':controller/:action/:id'
542
- end
543
-
544
- assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
545
- assert_equal '/', rs.generate(:controller => 'content')
546
-
547
- x = setup_for_named_route
548
- assert_equal("http://named.route.test/",
549
- x.send(:home_url))
550
- end
551
-
552
- def test_url_generated_when_forgetting_action
553
- [{:controller => 'content', :action => 'index'}, {:controller => 'content'}].each do |hash|
554
- rs.draw do |map|
555
- map.home '', hash
556
- map.connect ':controller/:action/:id'
557
- end
558
- assert_equal '/', rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'})
559
- assert_equal '/', rs.generate({:controller => 'content'})
560
- assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
561
- end
562
- end
563
-
564
- def test_named_route_method
565
- rs.draw do |map|
566
- map.categories 'categories', :controller => 'content', :action => 'categories'
567
- map.connect ':controller/:action/:id'
568
- end
569
-
570
- assert_equal '/categories', rs.generate(:controller => 'content', :action => 'categories')
571
- assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
572
- end
573
-
574
- def test_named_routes_array
575
- test_named_route_method
576
- assert_equal [:categories], rs.named_routes.names
577
- end
578
-
579
- def test_nil_defaults
580
- rs.draw do |map|
581
- map.connect 'journal',
582
- :controller => 'content',
583
- :action => 'list_journal',
584
- :date => nil, :user_id => nil
585
- map.connect ':controller/:action/:id'
586
- end
587
-
588
- assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil)
589
- end
590
-
591
- def setup_request_method_routes_for(method)
592
- @request = ActionController::TestRequest.new
593
- @request.env["REQUEST_METHOD"] = method
594
- @request.request_uri = "/match"
595
-
596
- rs.draw do |r|
597
- r.connect '/match', :controller => 'books', :action => 'get', :conditions => { :method => :get }
598
- r.connect '/match', :controller => 'books', :action => 'post', :conditions => { :method => :post }
599
- r.connect '/match', :controller => 'books', :action => 'put', :conditions => { :method => :put }
600
- r.connect '/match', :controller => 'books', :action => 'delete', :conditions => { :method => :delete }
601
- end
602
- end
603
-
604
- %w(GET POST PUT DELETE).each do |request_method|
605
- define_method("test_request_method_recognized_with_#{request_method}") do
606
- begin
607
- Object.const_set(:BooksController, Class.new(ActionController::Base))
608
-
609
- setup_request_method_routes_for(request_method)
610
-
611
- assert_nothing_raised { rs.recognize(@request) }
612
- assert_equal request_method.downcase, @request.path_parameters[:action]
613
- ensure
614
- Object.send(:remove_const, :BooksController) rescue nil
615
- end
616
- end
617
- end
618
-
619
- def test_subpath_recognized
620
- Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
621
-
622
- rs.draw do |r|
623
- r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
624
- r.connect '/items/:id/:action', :controller => 'subpath_books'
625
- r.connect '/posts/new/:action', :controller => 'subpath_books'
626
- r.connect '/posts/:id', :controller => 'subpath_books', :action => "show"
627
- end
628
-
629
- hash = rs.recognize_path "/books/17/edit"
630
- assert_not_nil hash
631
- assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]]
632
-
633
- hash = rs.recognize_path "/items/3/complete"
634
- assert_not_nil hash
635
- assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]]
636
-
637
- hash = rs.recognize_path "/posts/new/preview"
638
- assert_not_nil hash
639
- assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]]
640
-
641
- hash = rs.recognize_path "/posts/7"
642
- assert_not_nil hash
643
- assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
644
- ensure
645
- Object.send(:remove_const, :SubpathBooksController) rescue nil
646
- end
647
-
648
- def test_subpath_generated
649
- Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
650
-
651
- rs.draw do |r|
652
- r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
653
- r.connect '/items/:id/:action', :controller => 'subpath_books'
654
- r.connect '/posts/new/:action', :controller => 'subpath_books'
655
- end
656
-
657
- assert_equal "/books/7/edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit")
658
- assert_equal "/items/15/complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete")
659
- assert_equal "/posts/new/preview", rs.generate(:controller => "subpath_books", :action => "preview")
660
- ensure
661
- Object.send(:remove_const, :SubpathBooksController) rescue nil
662
- end
663
-
664
- def test_failed_requirements_raises_exception_with_violated_requirements
665
- rs.draw do |r|
666
- r.foo_with_requirement 'foos/:id', :controller=>'foos', :requirements=>{:id=>/\d+/}
667
- end
668
-
669
- x = setup_for_named_route
670
- assert_raises(ActionController::RoutingError) do
671
- x.send(:foo_with_requirement_url, "I am Against the requirements")
672
- end
673
- end
674
-
675
- def test_routes_changed_correctly_after_clear
676
- ActionController::Base.optimise_named_routes = true
677
- rs = ::ActionController::Routing::RouteSet.new
678
- rs.draw do |r|
679
- r.connect 'ca', :controller => 'ca', :action => "aa"
680
- r.connect 'cb', :controller => 'cb', :action => "ab"
681
- r.connect 'cc', :controller => 'cc', :action => "ac"
682
- r.connect ':controller/:action/:id'
683
- r.connect ':controller/:action/:id.:format'
684
- end
685
-
686
- hash = rs.recognize_path "/cc"
687
-
688
- assert_not_nil hash
689
- assert_equal %w(cc ac), [hash[:controller], hash[:action]]
690
-
691
- rs.draw do |r|
692
- r.connect 'cb', :controller => 'cb', :action => "ab"
693
- r.connect 'cc', :controller => 'cc', :action => "ac"
694
- r.connect ':controller/:action/:id'
695
- r.connect ':controller/:action/:id.:format'
696
- end
697
-
698
- hash = rs.recognize_path "/cc"
699
-
700
- assert_not_nil hash
701
- assert_equal %w(cc ac), [hash[:controller], hash[:action]]
702
- end
703
- end
704
-
705
62
  class SegmentTest < Test::Unit::TestCase
706
-
707
63
  def test_first_segment_should_interpolate_for_structure
708
64
  s = ROUTING::Segment.new
709
65
  def s.interpolation_statement(array) 'hello' end
710
66
  assert_equal 'hello', s.continue_string_structure([])
711
67
  end
712
-
68
+
713
69
  def test_interpolation_statement
714
- s = ROUTING::StaticSegment.new
715
- s.value = "Hello"
70
+ s = ROUTING::StaticSegment.new("Hello")
716
71
  assert_equal "Hello", eval(s.interpolation_statement([]))
717
72
  assert_equal "HelloHello", eval(s.interpolation_statement([s]))
718
-
719
- s2 = ROUTING::StaticSegment.new
720
- s2.value = "-"
73
+
74
+ s2 = ROUTING::StaticSegment.new("-")
721
75
  assert_equal "Hello-Hello", eval(s.interpolation_statement([s, s2]))
722
-
723
- s3 = ROUTING::StaticSegment.new
724
- s3.value = "World"
76
+
77
+ s3 = ROUTING::StaticSegment.new("World")
725
78
  assert_equal "Hello-World", eval(s3.interpolation_statement([s, s2]))
726
79
  end
727
-
728
80
  end
729
81
 
730
82
  class StaticSegmentTest < Test::Unit::TestCase
731
-
732
83
  def test_interpolation_chunk_should_respect_raw
733
- s = ROUTING::StaticSegment.new
734
- s.value = 'Hello World'
735
- assert ! s.raw?
84
+ s = ROUTING::StaticSegment.new('Hello World')
85
+ assert !s.raw?
736
86
  assert_equal 'Hello%20World', s.interpolation_chunk
737
87
 
738
- s.raw = true
88
+ s = ROUTING::StaticSegment.new('Hello World', :raw => true)
739
89
  assert s.raw?
740
90
  assert_equal 'Hello World', s.interpolation_chunk
741
91
  end
742
92
 
743
93
  def test_regexp_chunk_should_escape_specials
744
- s = ROUTING::StaticSegment.new
745
-
746
- s.value = 'Hello*World'
94
+ s = ROUTING::StaticSegment.new('Hello*World')
747
95
  assert_equal 'Hello\*World', s.regexp_chunk
748
-
749
- s.value = 'HelloWorld'
96
+
97
+ s = ROUTING::StaticSegment.new('HelloWorld')
750
98
  assert_equal 'HelloWorld', s.regexp_chunk
751
99
  end
752
-
100
+
753
101
  def test_regexp_chunk_should_add_question_mark_for_optionals
754
- s = ROUTING::StaticSegment.new
755
- s.value = "/"
756
- s.is_optional = true
102
+ s = ROUTING::StaticSegment.new("/", :optional => true)
757
103
  assert_equal "/?", s.regexp_chunk
758
-
759
- s.value = "hello"
104
+
105
+ s = ROUTING::StaticSegment.new("hello", :optional => true)
760
106
  assert_equal "(?:hello)?", s.regexp_chunk
761
107
  end
762
-
763
108
  end
764
109
 
765
110
  class DynamicSegmentTest < Test::Unit::TestCase
766
-
767
- def segment
111
+ def segment(options = {})
768
112
  unless @segment
769
- @segment = ROUTING::DynamicSegment.new
770
- @segment.key = :a
113
+ @segment = ROUTING::DynamicSegment.new(:a, options)
771
114
  end
772
115
  @segment
773
116
  end
774
-
117
+
775
118
  def test_extract_value
776
- s = ROUTING::DynamicSegment.new
777
- s.key = :a
778
-
119
+ s = ROUTING::DynamicSegment.new(:a)
120
+
779
121
  hash = {:a => '10', :b => '20'}
780
122
  assert_equal '10', eval(s.extract_value)
781
-
123
+
782
124
  hash = {:b => '20'}
783
125
  assert_equal nil, eval(s.extract_value)
784
-
126
+
785
127
  s.default = '20'
786
128
  assert_equal '20', eval(s.extract_value)
787
129
  end
788
-
130
+
789
131
  def test_default_local_name
790
132
  assert_equal 'a_value', segment.local_name,
791
133
  "Unexpected name -- all value_check tests will fail!"
792
134
  end
793
-
135
+
794
136
  def test_presence_value_check
795
137
  a_value = 10
796
138
  assert eval(segment.value_check)
797
139
  end
798
-
140
+
799
141
  def test_regexp_value_check_rejects_nil
800
- segment.regexp = /\d+/
142
+ segment = segment(:regexp => /\d+/)
143
+
801
144
  a_value = nil
802
- assert ! eval(segment.value_check)
145
+ assert !eval(segment.value_check)
803
146
  end
804
-
147
+
805
148
  def test_optional_regexp_value_check_should_accept_nil
806
- segment.regexp = /\d+/
807
- segment.is_optional = true
149
+ segment = segment(:regexp => /\d+/, :optional => true)
150
+
808
151
  a_value = nil
809
152
  assert eval(segment.value_check)
810
153
  end
811
-
154
+
812
155
  def test_regexp_value_check_rejects_no_match
813
- segment.regexp = /\d+/
814
-
156
+ segment = segment(:regexp => /\d+/)
157
+
815
158
  a_value = "Hello20World"
816
- assert ! eval(segment.value_check)
817
-
159
+ assert !eval(segment.value_check)
160
+
818
161
  a_value = "20Hi"
819
- assert ! eval(segment.value_check)
162
+ assert !eval(segment.value_check)
820
163
  end
821
-
164
+
822
165
  def test_regexp_value_check_accepts_match
823
- segment.regexp = /\d+/
824
-
166
+ segment = segment(:regexp => /\d+/)
825
167
  a_value = "30"
826
168
  assert eval(segment.value_check)
827
169
  end
828
-
170
+
829
171
  def test_value_check_fails_on_nil
830
172
  a_value = nil
831
173
  assert ! eval(segment.value_check)
832
174
  end
833
-
175
+
834
176
  def test_optional_value_needs_no_check
835
- segment.is_optional = true
177
+ segment = segment(:optional => true)
178
+
836
179
  a_value = nil
837
180
  assert_equal nil, segment.value_check
838
181
  end
839
-
182
+
840
183
  def test_regexp_value_check_should_accept_match_with_default
841
- segment.regexp = /\d+/
842
- segment.default = '200'
843
-
184
+ segment = segment(:regexp => /\d+/, :default => '200')
185
+
844
186
  a_value = '100'
845
187
  assert eval(segment.value_check)
846
188
  end
847
-
189
+
848
190
  def test_expiry_should_not_trigger_once_expired
849
191
  expired = true
850
192
  hash = merged = {:a => 2, :b => 3}
851
193
  options = {:b => 3}
852
194
  expire_on = Hash.new { raise 'No!!!' }
853
-
195
+
854
196
  eval(segment.expiry_statement)
855
197
  rescue RuntimeError
856
198
  flunk "Expiry check should not have occurred!"
857
199
  end
858
-
200
+
859
201
  def test_expiry_should_occur_according_to_expire_on
860
202
  expired = false
861
203
  hash = merged = {:a => 2, :b => 3}
862
204
  options = {:b => 3}
863
-
205
+
864
206
  expire_on = {:b => true, :a => false}
865
207
  eval(segment.expiry_statement)
866
208
  assert !expired
867
209
  assert_equal({:a => 2, :b => 3}, hash)
868
-
210
+
869
211
  expire_on = {:b => true, :a => true}
870
212
  eval(segment.expiry_statement)
871
213
  assert expired
872
214
  assert_equal({:b => 3}, hash)
873
215
  end
874
-
216
+
875
217
  def test_extraction_code_should_return_on_nil
876
218
  hash = merged = {:b => 3}
877
219
  options = {:b => 3}
878
220
  a_value = nil
879
-
221
+
880
222
  # Local jump because of return inside eval.
881
223
  assert_raises(LocalJumpError) { eval(segment.extraction_code) }
882
224
  end
883
-
225
+
884
226
  def test_extraction_code_should_return_on_mismatch
885
- segment.regexp = /\d+/
227
+ segment = segment(:regexp => /\d+/)
886
228
  hash = merged = {:a => 'Hi', :b => '3'}
887
229
  options = {:b => '3'}
888
230
  a_value = nil
889
-
231
+
890
232
  # Local jump because of return inside eval.
891
233
  assert_raises(LocalJumpError) { eval(segment.extraction_code) }
892
234
  end
893
-
235
+
894
236
  def test_extraction_code_should_accept_value_and_set_local
895
237
  hash = merged = {:a => 'Hi', :b => '3'}
896
238
  options = {:b => '3'}
@@ -900,351 +242,106 @@ class DynamicSegmentTest < Test::Unit::TestCase
900
242
  eval(segment.extraction_code)
901
243
  assert_equal 'Hi', a_value
902
244
  end
903
-
245
+
904
246
  def test_extraction_should_work_without_value_check
905
247
  segment.default = 'hi'
906
248
  hash = merged = {:b => '3'}
907
249
  options = {:b => '3'}
908
250
  a_value = nil
909
251
  expired = true
910
-
252
+
911
253
  eval(segment.extraction_code)
912
254
  assert_equal 'hi', a_value
913
255
  end
914
-
256
+
915
257
  def test_extraction_code_should_perform_expiry
916
258
  expired = false
917
259
  hash = merged = {:a => 'Hi', :b => '3'}
918
260
  options = {:b => '3'}
919
261
  expire_on = {:a => true}
920
262
  a_value = nil
921
-
263
+
922
264
  eval(segment.extraction_code)
923
265
  assert_equal 'Hi', a_value
924
266
  assert expired
925
267
  assert_equal options, hash
926
268
  end
927
-
269
+
928
270
  def test_interpolation_chunk_should_replace_value
929
271
  a_value = 'Hi'
930
272
  assert_equal a_value, eval(%("#{segment.interpolation_chunk}"))
931
273
  end
932
-
274
+
933
275
  def test_interpolation_chunk_should_accept_nil
934
276
  a_value = nil
935
277
  assert_equal '', eval(%("#{segment.interpolation_chunk('a_value')}"))
936
278
  end
937
-
279
+
938
280
  def test_value_regexp_should_be_nil_without_regexp
939
281
  assert_equal nil, segment.value_regexp
940
282
  end
941
-
283
+
942
284
  def test_value_regexp_should_match_exacly
943
- segment.regexp = /\d+/
285
+ segment = segment(:regexp => /\d+/)
944
286
  assert_no_match segment.value_regexp, "Hello 10 World"
945
287
  assert_no_match segment.value_regexp, "Hello 10"
946
288
  assert_no_match segment.value_regexp, "10 World"
947
289
  assert_match segment.value_regexp, "10"
948
290
  end
949
-
291
+
950
292
  def test_regexp_chunk_should_return_string
951
- segment.regexp = /\d+/
293
+ segment = segment(:regexp => /\d+/)
952
294
  assert_kind_of String, segment.regexp_chunk
953
295
  end
954
-
296
+
955
297
  def test_build_pattern_non_optional_with_no_captures
956
298
  # Non optional
957
- a_segment = ROUTING::DynamicSegment.new
958
- a_segment.regexp = /\d+/ #number_of_captures is 0
299
+ a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /\d+/)
959
300
  assert_equal "(\\d+)stuff", a_segment.build_pattern('stuff')
960
301
  end
961
302
 
962
303
  def test_build_pattern_non_optional_with_captures
963
304
  # Non optional
964
- a_segment = ROUTING::DynamicSegment.new
965
- a_segment.regexp = /(\d+)(.*?)/ #number_of_captures is 2
305
+ a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /(\d+)(.*?)/)
966
306
  assert_equal "((\\d+)(.*?))stuff", a_segment.build_pattern('stuff')
967
307
  end
968
308
 
969
309
  def test_optionality_implied
970
- a_segment = ROUTING::DynamicSegment.new
971
- a_segment.key = :id
310
+ a_segment = ROUTING::DynamicSegment.new(:id)
972
311
  assert a_segment.optionality_implied?
973
312
 
974
- a_segment.key = :action
313
+ a_segment = ROUTING::DynamicSegment.new(:action)
975
314
  assert a_segment.optionality_implied?
976
315
  end
977
316
 
978
317
  def test_modifiers_must_be_handled_sensibly
979
- a_segment = ROUTING::DynamicSegment.new
980
- a_segment.regexp = /david|jamis/i
318
+ a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /david|jamis/i)
981
319
  assert_equal "((?i-mx:david|jamis))stuff", a_segment.build_pattern('stuff')
982
- a_segment.regexp = /david|jamis/x
320
+ a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /david|jamis/x)
983
321
  assert_equal "((?x-mi:david|jamis))stuff", a_segment.build_pattern('stuff')
984
- a_segment.regexp = /david|jamis/
322
+ a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /david|jamis/)
985
323
  assert_equal "(david|jamis)stuff", a_segment.build_pattern('stuff')
986
324
  end
987
325
  end
988
326
 
989
327
  class ControllerSegmentTest < Test::Unit::TestCase
990
-
991
328
  def test_regexp_should_only_match_possible_controllers
992
329
  ActionController::Routing.with_controllers %w(admin/accounts admin/users account pages) do
993
330
  cs = ROUTING::ControllerSegment.new :controller
994
331
  regexp = %r{\A#{cs.regexp_chunk}\Z}
995
-
332
+
996
333
  ActionController::Routing.possible_controllers.each do |name|
997
334
  assert_match regexp, name
998
335
  assert_no_match regexp, "#{name}_fake"
999
-
336
+
1000
337
  match = regexp.match name
1001
338
  assert_equal name, match[1]
1002
339
  end
1003
340
  end
1004
341
  end
1005
-
1006
- end
1007
-
1008
- uses_mocha 'RouteTest' do
1009
-
1010
- class MockController
1011
- attr_accessor :routes
1012
-
1013
- def initialize(routes)
1014
- self.routes = routes
1015
- end
1016
-
1017
- def url_for(options)
1018
- only_path = options.delete(:only_path)
1019
-
1020
- port = options.delete(:port) || 80
1021
- port_string = port == 80 ? '' : ":#{port}"
1022
-
1023
- host = options.delete(:host) || "named.route.test"
1024
- anchor = "##{options.delete(:anchor)}" if options.key?(:anchor)
1025
-
1026
- path = routes.generate(options)
1027
-
1028
- only_path ? "#{path}#{anchor}" : "http://#{host}#{port_string}#{path}#{anchor}"
1029
- end
1030
-
1031
- def request
1032
- @request ||= MockRequest.new(:host => "named.route.test", :method => :get)
1033
- end
1034
-
1035
- def relative_url_root=(value)
1036
- request.relative_url_root=value
1037
- end
1038
- end
1039
-
1040
- class MockRequest
1041
- attr_accessor :path, :path_parameters, :host, :subdomains, :domain,
1042
- :method, :relative_url_root
1043
-
1044
- def initialize(values={})
1045
- values.each { |key, value| send("#{key}=", value) }
1046
- if values[:host]
1047
- subdomain, self.domain = values[:host].split(/\./, 2)
1048
- self.subdomains = [subdomain]
1049
- end
1050
- end
1051
-
1052
- def protocol
1053
- "http://"
1054
- end
1055
-
1056
- def host_with_port
1057
- (subdomains * '.') + '.' + domain
1058
- end
1059
- end
1060
-
1061
- class RouteTest < Test::Unit::TestCase
1062
-
1063
- def setup
1064
- @route = ROUTING::Route.new
1065
- end
1066
-
1067
- def slash_segment(is_optional = false)
1068
- returning ROUTING::DividerSegment.new('/') do |s|
1069
- s.is_optional = is_optional
1070
- end
1071
- end
1072
-
1073
- def default_route
1074
- unless defined?(@default_route)
1075
- @default_route = ROUTING::Route.new
1076
-
1077
- @default_route.segments << (s = ROUTING::StaticSegment.new)
1078
- s.value = '/'
1079
- s.raw = true
1080
-
1081
- @default_route.segments << (s = ROUTING::DynamicSegment.new)
1082
- s.key = :controller
1083
-
1084
- @default_route.segments << slash_segment(:optional)
1085
- @default_route.segments << (s = ROUTING::DynamicSegment.new)
1086
- s.key = :action
1087
- s.default = 'index'
1088
- s.is_optional = true
1089
-
1090
- @default_route.segments << slash_segment(:optional)
1091
- @default_route.segments << (s = ROUTING::DynamicSegment.new)
1092
- s.key = :id
1093
- s.is_optional = true
1094
-
1095
- @default_route.segments << slash_segment(:optional)
1096
- end
1097
- @default_route
1098
- end
1099
-
1100
- def test_default_route_recognition
1101
- expected = {:controller => 'accounts', :action => 'show', :id => '10'}
1102
- assert_equal expected, default_route.recognize('/accounts/show/10')
1103
- assert_equal expected, default_route.recognize('/accounts/show/10/')
1104
-
1105
- expected[:id] = 'jamis'
1106
- assert_equal expected, default_route.recognize('/accounts/show/jamis/')
1107
-
1108
- expected.delete :id
1109
- assert_equal expected, default_route.recognize('/accounts/show')
1110
- assert_equal expected, default_route.recognize('/accounts/show/')
1111
-
1112
- expected[:action] = 'index'
1113
- assert_equal expected, default_route.recognize('/accounts/')
1114
- assert_equal expected, default_route.recognize('/accounts')
1115
-
1116
- assert_equal nil, default_route.recognize('/')
1117
- assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free')
1118
- end
1119
-
1120
- def test_default_route_should_omit_default_action
1121
- o = {:controller => 'accounts', :action => 'index'}
1122
- assert_equal '/accounts', default_route.generate(o, o, {})
1123
- end
1124
-
1125
- def test_default_route_should_include_default_action_when_id_present
1126
- o = {:controller => 'accounts', :action => 'index', :id => '20'}
1127
- assert_equal '/accounts/index/20', default_route.generate(o, o, {})
1128
- end
1129
-
1130
- def test_default_route_should_work_with_action_but_no_id
1131
- o = {:controller => 'accounts', :action => 'list_all'}
1132
- assert_equal '/accounts/list_all', default_route.generate(o, o, {})
1133
- end
1134
-
1135
- def test_default_route_should_uri_escape_pluses
1136
- expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' }
1137
- assert_equal expected, default_route.recognize('/accounts/show/hello world')
1138
- assert_equal expected, default_route.recognize('/accounts/show/hello%20world')
1139
- assert_equal '/accounts/show/hello%20world', default_route.generate(expected, expected, {})
1140
-
1141
- expected[:id] = 'hello+world'
1142
- assert_equal expected, default_route.recognize('/accounts/show/hello+world')
1143
- assert_equal expected, default_route.recognize('/accounts/show/hello%2Bworld')
1144
- assert_equal '/accounts/show/hello+world', default_route.generate(expected, expected, {})
1145
- end
1146
-
1147
- def test_matches_controller_and_action
1148
- # requirement_for should only be called for the action and controller _once_
1149
- @route.expects(:requirement_for).with(:controller).times(1).returns('pages')
1150
- @route.expects(:requirement_for).with(:action).times(1).returns('show')
1151
-
1152
- @route.requirements = {:controller => 'pages', :action => 'show'}
1153
- assert @route.matches_controller_and_action?('pages', 'show')
1154
- assert !@route.matches_controller_and_action?('not_pages', 'show')
1155
- assert !@route.matches_controller_and_action?('pages', 'not_show')
1156
- end
1157
-
1158
- def test_parameter_shell
1159
- page_url = ROUTING::Route.new
1160
- page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/}
1161
- assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell)
1162
- end
1163
-
1164
- def test_defaults
1165
- route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html"
1166
- assert_equal(
1167
- { :controller => "users", :action => "show", :format => "html" },
1168
- route.defaults)
1169
- end
1170
-
1171
- def test_builder_complains_without_controller
1172
- assert_raises(ArgumentError) do
1173
- ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index"
1174
- end
1175
- end
1176
-
1177
- def test_significant_keys_for_default_route
1178
- keys = default_route.significant_keys.sort_by {|k| k.to_s }
1179
- assert_equal [:action, :controller, :id], keys
1180
- end
1181
-
1182
- def test_significant_keys
1183
- user_url = ROUTING::Route.new
1184
- user_url.segments << (s = ROUTING::StaticSegment.new)
1185
- s.value = '/'
1186
- s.raw = true
1187
-
1188
- user_url.segments << (s = ROUTING::StaticSegment.new)
1189
- s.value = 'user'
1190
-
1191
- user_url.segments << (s = ROUTING::StaticSegment.new)
1192
- s.value = '/'
1193
- s.raw = true
1194
- s.is_optional = true
1195
-
1196
- user_url.segments << (s = ROUTING::DynamicSegment.new)
1197
- s.key = :user
1198
-
1199
- user_url.segments << (s = ROUTING::StaticSegment.new)
1200
- s.value = '/'
1201
- s.raw = true
1202
- s.is_optional = true
1203
-
1204
- user_url.requirements = {:controller => 'users', :action => 'show'}
1205
-
1206
- keys = user_url.significant_keys.sort_by { |k| k.to_s }
1207
- assert_equal [:action, :controller, :user], keys
1208
- end
1209
-
1210
- def test_build_empty_query_string
1211
- assert_equal '', @route.build_query_string({})
1212
- end
1213
-
1214
- def test_build_query_string_with_nil_value
1215
- assert_equal '', @route.build_query_string({:x => nil})
1216
- end
1217
-
1218
- def test_simple_build_query_string
1219
- assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2'))
1220
- end
1221
-
1222
- def test_convert_ints_build_query_string
1223
- assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2))
1224
- end
1225
-
1226
- def test_escape_spaces_build_query_string
1227
- assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world'))
1228
- end
1229
-
1230
- def test_expand_array_build_query_string
1231
- assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2]))
1232
- end
1233
-
1234
- def test_escape_spaces_build_query_string_selected_keys
1235
- assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x]))
1236
- end
1237
-
1238
- private
1239
- def order_query_string(qs)
1240
- '?' + qs[1..-1].split('&').sort.join('&')
1241
- end
1242
342
  end
1243
343
 
1244
- end # uses_mocha
1245
-
1246
344
  class RouteBuilderTest < Test::Unit::TestCase
1247
-
1248
345
  def builder
1249
346
  @builder ||= ROUTING::RouteBuilder.new
1250
347
  end
@@ -1273,7 +370,7 @@ class RouteBuilderTest < Test::Unit::TestCase
1273
370
  assert_kind_of ROUTING::StaticSegment, segment
1274
371
  assert_equal 'ulysses', segment.value
1275
372
  end
1276
-
373
+
1277
374
  def test_segment_for_action
1278
375
  segment, rest = builder.segment_for ':action'
1279
376
  assert_equal '', rest
@@ -1281,7 +378,7 @@ class RouteBuilderTest < Test::Unit::TestCase
1281
378
  assert_equal :action, segment.key
1282
379
  assert_equal 'index', segment.default
1283
380
  end
1284
-
381
+
1285
382
  def test_segment_for_dynamic
1286
383
  segment, rest = builder.segment_for ':login'
1287
384
  assert_equal '', rest
@@ -1290,7 +387,7 @@ class RouteBuilderTest < Test::Unit::TestCase
1290
387
  assert_equal nil, segment.default
1291
388
  assert ! segment.optional?
1292
389
  end
1293
-
390
+
1294
391
  def test_segment_for_with_rest
1295
392
  segment, rest = builder.segment_for ':login/:action'
1296
393
  assert_equal :login, segment.key
@@ -1302,105 +399,104 @@ class RouteBuilderTest < Test::Unit::TestCase
1302
399
  assert_equal :action, segment.key
1303
400
  assert_equal '', rest
1304
401
  end
1305
-
402
+
1306
403
  def test_segments_for
1307
404
  segments = builder.segments_for_route_path '/:controller/:action/:id'
1308
-
405
+
1309
406
  assert_kind_of ROUTING::DividerSegment, segments[0]
1310
407
  assert_equal '/', segments[2].value
1311
-
408
+
1312
409
  assert_kind_of ROUTING::DynamicSegment, segments[1]
1313
410
  assert_equal :controller, segments[1].key
1314
-
411
+
1315
412
  assert_kind_of ROUTING::DividerSegment, segments[2]
1316
413
  assert_equal '/', segments[2].value
1317
-
414
+
1318
415
  assert_kind_of ROUTING::DynamicSegment, segments[3]
1319
416
  assert_equal :action, segments[3].key
1320
-
417
+
1321
418
  assert_kind_of ROUTING::DividerSegment, segments[4]
1322
419
  assert_equal '/', segments[4].value
1323
-
420
+
1324
421
  assert_kind_of ROUTING::DynamicSegment, segments[5]
1325
422
  assert_equal :id, segments[5].key
1326
423
  end
1327
-
424
+
1328
425
  def test_segment_for_action
1329
426
  s, r = builder.segment_for(':action/something/else')
1330
427
  assert_equal '/something/else', r
1331
428
  assert_equal :action, s.key
1332
429
  end
1333
-
430
+
1334
431
  def test_action_default_should_not_trigger_on_prefix
1335
432
  s, r = builder.segment_for ':action_name/something/else'
1336
433
  assert_equal '/something/else', r
1337
434
  assert_equal :action_name, s.key
1338
435
  assert_equal nil, s.default
1339
436
  end
1340
-
437
+
1341
438
  def test_divide_route_options
1342
439
  segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1343
440
  defaults, requirements = builder.divide_route_options(segments,
1344
441
  :action => 'buy', :person => /\w+/, :car => /\w+/,
1345
442
  :defaults => {:person => nil, :car => nil}
1346
443
  )
1347
-
444
+
1348
445
  assert_equal({:action => 'buy', :person => nil, :car => nil}, defaults)
1349
446
  assert_equal({:person => /\w+/, :car => /\w+/}, requirements)
1350
447
  end
1351
-
448
+
1352
449
  def test_assign_route_options
1353
450
  segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1354
451
  defaults = {:action => 'buy', :person => nil, :car => nil}
1355
452
  requirements = {:person => /\w+/, :car => /\w+/}
1356
-
453
+
1357
454
  route_requirements = builder.assign_route_options(segments, defaults, requirements)
1358
455
  assert_equal({}, route_requirements)
1359
-
456
+
1360
457
  assert_equal :action, segments[3].key
1361
458
  assert_equal 'buy', segments[3].default
1362
-
459
+
1363
460
  assert_equal :person, segments[5].key
1364
461
  assert_equal %r/\w+/, segments[5].regexp
1365
462
  assert segments[5].optional?
1366
-
463
+
1367
464
  assert_equal :car, segments[7].key
1368
465
  assert_equal %r/\w+/, segments[7].regexp
1369
466
  assert segments[7].optional?
1370
467
  end
1371
-
468
+
1372
469
  def test_assign_route_options_with_anchor_chars
1373
470
  segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1374
471
  defaults = {:action => 'buy', :person => nil, :car => nil}
1375
472
  requirements = {:person => /\w+/, :car => /^\w+$/}
1376
-
473
+
1377
474
  assert_raises ArgumentError do
1378
475
  route_requirements = builder.assign_route_options(segments, defaults, requirements)
1379
476
  end
1380
-
477
+
1381
478
  requirements[:car] = /[^\/]+/
1382
479
  route_requirements = builder.assign_route_options(segments, defaults, requirements)
1383
480
  end
1384
-
1385
481
 
1386
482
  def test_optional_segments_preceding_required_segments
1387
483
  segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1388
484
  defaults = {:action => 'buy', :person => nil, :car => "model-t"}
1389
485
  assert builder.assign_route_options(segments, defaults, {}).empty?
1390
-
486
+
1391
487
  0.upto(1) { |i| assert !segments[i].optional?, "segment #{i} is optional and it shouldn't be" }
1392
488
  assert segments[2].optional?
1393
-
489
+
1394
490
  assert_equal nil, builder.warn_output # should only warn on the :person segment
1395
491
  end
1396
-
492
+
1397
493
  def test_segmentation_of_dot_path
1398
494
  segments = builder.segments_for_route_path '/books/:action.rss'
1399
495
  assert builder.assign_route_options(segments, {}, {}).empty?
1400
496
  assert_equal 6, segments.length # "/", "books", "/", ":action", ".", "rss"
1401
497
  assert !segments.any? { |seg| seg.optional? }
1402
498
  end
1403
-
499
+
1404
500
  def test_segmentation_of_dynamic_dot_path
1405
501
  segments = builder.segments_for_route_path '/books/:action.:format'
1406
502
  assert builder.assign_route_options(segments, {}, {}).empty?
@@ -1408,56 +504,56 @@ class RouteBuilderTest < Test::Unit::TestCase
1408
504
  assert !segments.any? { |seg| seg.optional? }
1409
505
  assert_kind_of ROUTING::DynamicSegment, segments.last
1410
506
  end
1411
-
507
+
1412
508
  def test_assignment_of_default_options
1413
509
  segments = builder.segments_for_route_path '/:controller/:action/:id/'
1414
510
  action, id = segments[-4], segments[-2]
1415
-
511
+
1416
512
  assert_equal :action, action.key
1417
513
  assert_equal :id, id.key
1418
514
  assert ! action.optional?
1419
515
  assert ! id.optional?
1420
-
516
+
1421
517
  builder.assign_default_route_options(segments)
1422
-
518
+
1423
519
  assert_equal 'index', action.default
1424
520
  assert action.optional?
1425
521
  assert id.optional?
1426
522
  end
1427
-
523
+
1428
524
  def test_assignment_of_default_options_respects_existing_defaults
1429
525
  segments = builder.segments_for_route_path '/:controller/:action/:id/'
1430
526
  action, id = segments[-4], segments[-2]
1431
-
527
+
1432
528
  assert_equal :action, action.key
1433
529
  assert_equal :id, id.key
1434
530
  action.default = 'show'
1435
531
  action.is_optional = true
1436
-
532
+
1437
533
  id.default = 'Welcome'
1438
534
  id.is_optional = true
1439
-
535
+
1440
536
  builder.assign_default_route_options(segments)
1441
-
537
+
1442
538
  assert_equal 'show', action.default
1443
539
  assert action.optional?
1444
540
  assert_equal 'Welcome', id.default
1445
541
  assert id.optional?
1446
542
  end
1447
-
543
+
1448
544
  def test_assignment_of_default_options_respects_regexps
1449
545
  segments = builder.segments_for_route_path '/:controller/:action/:id/'
1450
546
  action = segments[-4]
1451
-
547
+
1452
548
  assert_equal :action, action.key
1453
- action.regexp = /show|in/ # Use 'in' to check partial matches
1454
-
549
+ segments[-4] = ROUTING::DynamicSegment.new(:action, :regexp => /show|in/)
550
+
1455
551
  builder.assign_default_route_options(segments)
1456
-
552
+
1457
553
  assert_equal nil, action.default
1458
554
  assert ! action.optional?
1459
555
  end
1460
-
556
+
1461
557
  def test_assignment_of_is_optional_when_default
1462
558
  segments = builder.segments_for_route_path '/books/:action.rss'
1463
559
  assert_equal segments[3].key, :action
@@ -1465,44 +561,44 @@ class RouteBuilderTest < Test::Unit::TestCase
1465
561
  builder.ensure_required_segments(segments)
1466
562
  assert ! segments[3].optional?
1467
563
  end
1468
-
564
+
1469
565
  def test_is_optional_is_assigned_to_default_segments
1470
566
  segments = builder.segments_for_route_path '/books/:action'
1471
567
  builder.assign_route_options(segments, {:action => 'index'}, {})
1472
-
568
+
1473
569
  assert_equal segments[3].key, :action
1474
570
  assert segments[3].optional?
1475
571
  assert_kind_of ROUTING::DividerSegment, segments[2]
1476
572
  assert segments[2].optional?
1477
573
  end
1478
-
574
+
1479
575
  # XXX is optional not being set right?
1480
576
  # /blah/:defaulted_segment <-- is the second slash optional? it should be.
1481
-
577
+
1482
578
  def test_route_build
1483
579
  ActionController::Routing.with_controllers %w(users pages) do
1484
580
  r = builder.build '/:controller/:action/:id/', :action => nil
1485
-
581
+
1486
582
  [0, 2, 4].each do |i|
1487
583
  assert_kind_of ROUTING::DividerSegment, r.segments[i]
1488
584
  assert_equal '/', r.segments[i].value
1489
585
  assert r.segments[i].optional? if i > 1
1490
586
  end
1491
-
587
+
1492
588
  assert_kind_of ROUTING::DynamicSegment, r.segments[1]
1493
589
  assert_equal :controller, r.segments[1].key
1494
590
  assert_equal nil, r.segments[1].default
1495
-
591
+
1496
592
  assert_kind_of ROUTING::DynamicSegment, r.segments[3]
1497
593
  assert_equal :action, r.segments[3].key
1498
594
  assert_equal 'index', r.segments[3].default
1499
-
595
+
1500
596
  assert_kind_of ROUTING::DynamicSegment, r.segments[5]
1501
597
  assert_equal :id, r.segments[5].key
1502
598
  assert r.segments[5].optional?
1503
599
  end
1504
600
  end
1505
-
601
+
1506
602
  def test_slashes_are_implied
1507
603
  routes = [
1508
604
  builder.build('/:controller/:action/:id/', :action => nil),
@@ -1516,886 +612,1791 @@ class RouteBuilderTest < Test::Unit::TestCase
1516
612
  assert_equal expected, found, "Route #{i + 1} has #{found} segments, expected #{expected}"
1517
613
  end
1518
614
  end
1519
-
1520
615
  end
1521
616
 
617
+ class RoutingTest < Test::Unit::TestCase
618
+ def test_possible_controllers
619
+ true_controller_paths = ActionController::Routing.controller_paths
1522
620
 
621
+ ActionController::Routing.use_controllers! nil
1523
622
 
1524
-
1525
- class RouteSetTest < Test::Unit::TestCase
1526
-
1527
- def set
1528
- @set ||= ROUTING::RouteSet.new
1529
- end
1530
-
1531
- def request
1532
- @request ||= MockRequest.new(:host => "named.routes.test", :method => :get)
1533
- end
1534
-
1535
- def test_generate_extras
1536
- set.draw { |m| m.connect ':controller/:action/:id' }
1537
- path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1538
- assert_equal "/foo/bar/15", path
1539
- assert_equal %w(that this), extras.map(&:to_s).sort
1540
- end
1541
-
1542
- def test_extra_keys
1543
- set.draw { |m| m.connect ':controller/:action/:id' }
1544
- extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1545
- assert_equal %w(that this), extras.map(&:to_s).sort
1546
- end
1547
-
1548
- def test_generate_extras_not_first
1549
- set.draw do |map|
1550
- map.connect ':controller/:action/:id.:format'
1551
- map.connect ':controller/:action/:id'
1552
- end
1553
- path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1554
- assert_equal "/foo/bar/15", path
1555
- assert_equal %w(that this), extras.map(&:to_s).sort
1556
- end
1557
-
1558
- def test_generate_not_first
1559
- set.draw do |map|
1560
- map.connect ':controller/:action/:id.:format'
1561
- map.connect ':controller/:action/:id'
1562
- end
1563
- assert_equal "/foo/bar/15?this=hello", set.generate(:controller => "foo", :action => "bar", :id => 15, :this => "hello")
1564
- end
1565
-
1566
- def test_extra_keys_not_first
1567
- set.draw do |map|
1568
- map.connect ':controller/:action/:id.:format'
1569
- map.connect ':controller/:action/:id'
623
+ silence_warnings do
624
+ Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
1570
625
  end
1571
- extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1572
- assert_equal %w(that this), extras.map(&:to_s).sort
1573
- end
1574
626
 
1575
- def test_draw
1576
- assert_equal 0, set.routes.size
1577
- set.draw do |map|
1578
- map.connect '/hello/world', :controller => 'a', :action => 'b'
1579
- end
1580
- assert_equal 1, set.routes.size
1581
- end
1582
-
1583
- def test_named_draw
1584
- assert_equal 0, set.routes.size
1585
- set.draw do |map|
1586
- map.hello '/hello/world', :controller => 'a', :action => 'b'
1587
- end
1588
- assert_equal 1, set.routes.size
1589
- assert_equal set.routes.first, set.named_routes[:hello]
1590
- end
1591
-
1592
- def test_later_named_routes_take_precedence
1593
- set.draw do |map|
1594
- map.hello '/hello/world', :controller => 'a', :action => 'b'
1595
- map.hello '/hello', :controller => 'a', :action => 'b'
1596
- end
1597
- assert_equal set.routes.last, set.named_routes[:hello]
1598
- end
627
+ ActionController::Routing.controller_paths = [
628
+ RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib'
629
+ ]
1599
630
 
1600
- def setup_named_route_test
1601
- set.draw do |map|
1602
- map.show '/people/:id', :controller => 'people', :action => 'show'
1603
- map.index '/people', :controller => 'people', :action => 'index'
1604
- map.multi '/people/go/:foo/:bar/joe/:id', :controller => 'people', :action => 'multi'
1605
- map.users '/admin/users', :controller => 'admin/users', :action => 'index'
631
+ assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
632
+ ensure
633
+ if true_controller_paths
634
+ ActionController::Routing.controller_paths = true_controller_paths
1606
635
  end
1607
-
1608
- klass = Class.new(MockController)
1609
- set.install_helpers(klass)
1610
- klass.new(set)
1611
- end
1612
-
1613
- def test_named_route_hash_access_method
1614
- controller = setup_named_route_test
1615
-
1616
- assert_equal(
1617
- { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => false },
1618
- controller.send(:hash_for_show_url, :id => 5))
1619
-
1620
- assert_equal(
1621
- { :controller => 'people', :action => 'index', :use_route => :index, :only_path => false },
1622
- controller.send(:hash_for_index_url))
1623
-
1624
- assert_equal(
1625
- { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => true },
1626
- controller.send(:hash_for_show_path, :id => 5)
1627
- )
1628
- end
1629
-
1630
- def test_named_route_url_method
1631
- controller = setup_named_route_test
1632
-
1633
- assert_equal "http://named.route.test/people/5", controller.send(:show_url, :id => 5)
1634
- assert_equal "/people/5", controller.send(:show_path, :id => 5)
1635
-
1636
- assert_equal "http://named.route.test/people", controller.send(:index_url)
1637
- assert_equal "/people", controller.send(:index_path)
1638
-
1639
- assert_equal "http://named.route.test/admin/users", controller.send(:users_url)
1640
- assert_equal '/admin/users', controller.send(:users_path)
1641
- assert_equal '/admin/users', set.generate(controller.send(:hash_for_users_url), {:controller => 'users', :action => 'index'})
636
+ ActionController::Routing.use_controllers! nil
637
+ Object.send(:remove_const, :RAILS_ROOT) rescue nil
1642
638
  end
1643
639
 
1644
- def test_named_route_url_method_with_anchor
1645
- controller = setup_named_route_test
1646
-
1647
- assert_equal "http://named.route.test/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location')
1648
- assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location')
640
+ def test_possible_controllers_are_reset_on_each_load
641
+ true_possible_controllers = ActionController::Routing.possible_controllers
642
+ true_controller_paths = ActionController::Routing.controller_paths
1649
643
 
1650
- assert_equal "http://named.route.test/people#location", controller.send(:index_url, :anchor => 'location')
1651
- assert_equal "/people#location", controller.send(:index_path, :anchor => 'location')
644
+ ActionController::Routing.use_controllers! nil
645
+ root = File.dirname(__FILE__) + '/controller_fixtures'
1652
646
 
1653
- assert_equal "http://named.route.test/admin/users#location", controller.send(:users_url, :anchor => 'location')
1654
- assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location')
647
+ ActionController::Routing.controller_paths = []
648
+ assert_equal [], ActionController::Routing.possible_controllers
1655
649
 
1656
- assert_equal "http://named.route.test/people/go/7/hello/joe/5#location",
1657
- controller.send(:multi_url, 7, "hello", 5, :anchor => 'location')
650
+ ActionController::Routing.controller_paths = [
651
+ root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib'
652
+ ]
653
+ ActionController::Routing::Routes.load!
1658
654
 
1659
- assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar#location",
1660
- controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location')
655
+ assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
656
+ ensure
657
+ ActionController::Routing.controller_paths = true_controller_paths
658
+ ActionController::Routing.use_controllers! true_possible_controllers
659
+ Object.send(:remove_const, :RAILS_ROOT) rescue nil
1661
660
 
1662
- assert_equal "http://named.route.test/people?baz=bar#location",
1663
- controller.send(:index_url, :baz => "bar", :anchor => 'location')
1664
- end
1665
-
1666
- def test_named_route_url_method_with_port
1667
- controller = setup_named_route_test
1668
- assert_equal "http://named.route.test:8080/people/5", controller.send(:show_url, 5, :port=>8080)
1669
- end
1670
-
1671
- def test_named_route_url_method_with_host
1672
- controller = setup_named_route_test
1673
- assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com")
661
+ ActionController::Routing::Routes.clear!
662
+ ActionController::Routing::Routes.load_routes!
1674
663
  end
1675
-
1676
664
 
1677
- def test_named_route_url_method_with_ordered_parameters
1678
- controller = setup_named_route_test
1679
- assert_equal "http://named.route.test/people/go/7/hello/joe/5",
1680
- controller.send(:multi_url, 7, "hello", 5)
665
+ def test_with_controllers
666
+ c = %w(admin/accounts admin/users account pages)
667
+ ActionController::Routing.with_controllers c do
668
+ assert_equal c, ActionController::Routing.possible_controllers
669
+ end
1681
670
  end
1682
671
 
1683
- def test_named_route_url_method_with_ordered_parameters_and_hash
1684
- controller = setup_named_route_test
1685
- assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar",
1686
- controller.send(:multi_url, 7, "hello", 5, :baz => "bar")
672
+ def test_normalize_unix_paths
673
+ load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models .foo/../.bar foo.bar/../config)
674
+ paths = ActionController::Routing.normalize_paths(load_paths)
675
+ assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models config .bar lib .), paths
1687
676
  end
1688
-
1689
- def test_named_route_url_method_with_no_positional_arguments
1690
- controller = setup_named_route_test
1691
- assert_equal "http://named.route.test/people?baz=bar",
1692
- controller.send(:index_url, :baz => "bar")
677
+
678
+ def test_normalize_windows_paths
679
+ load_paths = %w(. config\\..\\app\\controllers config\\..\\app\\\\helpers script\\..\\config\\..\\vendor\\rails\\actionpack\\lib vendor\\rails\\railties\\builtin\\rails_info app\\models lib script\\..\\config\\..\\foo\\bar\\..\\..\\app\\models .foo\\..\\.bar foo.bar\\..\\config)
680
+ paths = ActionController::Routing.normalize_paths(load_paths)
681
+ assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models config .bar lib .), paths
1693
682
  end
1694
-
1695
- def test_draw_default_route
1696
- ActionController::Routing.with_controllers(['users']) do
1697
- set.draw do |map|
1698
- map.connect '/:controller/:action/:id'
1699
- end
1700
683
 
1701
- assert_equal 1, set.routes.size
1702
- route = set.routes.first
684
+ def test_routing_helper_module
685
+ assert_kind_of Module, ActionController::Routing::Helpers
1703
686
 
1704
- assert route.segments.last.optional?
687
+ h = ActionController::Routing::Helpers
688
+ c = Class.new
689
+ assert ! c.ancestors.include?(h)
690
+ ActionController::Routing::Routes.install_helpers c
691
+ assert c.ancestors.include?(h)
692
+ end
693
+ end
1705
694
 
1706
- assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10)
1707
- assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10)
695
+ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
696
+ class MockController
697
+ attr_accessor :routes
1708
698
 
1709
- assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
1710
- assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
699
+ def initialize(routes)
700
+ self.routes = routes
1711
701
  end
1712
- end
1713
702
 
1714
- def test_draw_default_route_with_default_controller
1715
- ActionController::Routing.with_controllers(['users']) do
1716
- set.draw do |map|
1717
- map.connect '/:controller/:action/:id', :controller => 'users'
1718
- end
1719
- assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/'))
1720
- end
1721
- end
703
+ def url_for(options)
704
+ only_path = options.delete(:only_path)
1722
705
 
1723
- def test_route_with_parameter_shell
1724
- ActionController::Routing.with_controllers(['users', 'pages']) do
1725
- set.draw do |map|
1726
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
1727
- map.connect '/:controller/:action/:id'
1728
- end
706
+ port = options.delete(:port) || 80
707
+ port_string = port == 80 ? '' : ":#{port}"
1729
708
 
1730
- assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
1731
- assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
1732
- assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
709
+ protocol = options.delete(:protocol) || "http"
710
+ host = options.delete(:host) || "named.route.test"
711
+ anchor = "##{options.delete(:anchor)}" if options.key?(:anchor)
1733
712
 
1734
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
1735
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
1736
- end
1737
- end
713
+ path = routes.generate(options)
1738
714
 
1739
- def test_route_requirements_with_anchor_chars_are_invalid
1740
- assert_raises ArgumentError do
1741
- set.draw do |map|
1742
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/
1743
- end
1744
- end
1745
- assert_raises ArgumentError do
1746
- set.draw do |map|
1747
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/
1748
- end
715
+ only_path ? "#{path}#{anchor}" : "#{protocol}://#{host}#{port_string}#{path}#{anchor}"
1749
716
  end
1750
- assert_raises ArgumentError do
1751
- set.draw do |map|
1752
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/
1753
- end
1754
- end
1755
- assert_raises ArgumentError do
1756
- set.draw do |map|
1757
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/
1758
- end
1759
- end
1760
- assert_raises ArgumentError do
1761
- set.draw do |map|
1762
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/
1763
- end
1764
- end
1765
- assert_nothing_raised do
1766
- set.draw do |map|
1767
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/
1768
- end
1769
- assert_raises ActionController::RoutingError do
1770
- set.generate :controller => 'pages', :action => 'show', :id => 10
1771
- end
1772
- end
1773
- end
1774
717
 
1775
- def test_non_path_route_requirements_match_all
1776
- set.draw do |map|
1777
- map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/
1778
- end
1779
- assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis')
1780
- assert_raises ActionController::RoutingError do
1781
- set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis')
1782
- end
1783
- assert_raises ActionController::RoutingError do
1784
- set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david')
1785
- end
1786
- end
1787
-
1788
- def test_recognize_with_encoded_id_and_regex
1789
- set.draw do |map|
1790
- map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/
718
+ def request
719
+ @request ||= MockRequest.new(:host => "named.route.test", :method => :get)
1791
720
  end
1792
-
1793
- assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
1794
- assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world'))
1795
721
  end
1796
722
 
1797
- def test_recognize_with_conditions
1798
- Object.const_set(:PeopleController, Class.new)
723
+ class MockRequest
724
+ attr_accessor :path, :path_parameters, :host, :subdomains, :domain, :method
1799
725
 
1800
- set.draw do |map|
1801
- map.with_options(:controller => "people") do |people|
1802
- people.people "/people", :action => "index", :conditions => { :method => :get }
1803
- people.connect "/people", :action => "create", :conditions => { :method => :post }
1804
- people.person "/people/:id", :action => "show", :conditions => { :method => :get }
1805
- people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
1806
- people.connect "/people/:id", :action => "destroy", :conditions => { :method => :delete }
726
+ def initialize(values={})
727
+ values.each { |key, value| send("#{key}=", value) }
728
+ if values[:host]
729
+ subdomain, self.domain = values[:host].split(/\./, 2)
730
+ self.subdomains = [subdomain]
1807
731
  end
1808
732
  end
1809
733
 
1810
- request.path = "/people"
1811
- request.method = :get
1812
- assert_nothing_raised { set.recognize(request) }
1813
- assert_equal("index", request.path_parameters[:action])
1814
-
1815
- request.method = :post
1816
- assert_nothing_raised { set.recognize(request) }
1817
- assert_equal("create", request.path_parameters[:action])
1818
-
1819
- request.method = :put
1820
- assert_nothing_raised { set.recognize(request) }
1821
- assert_equal("update", request.path_parameters[:action])
734
+ def protocol
735
+ "http://"
736
+ end
1822
737
 
1823
- begin
1824
- request.method = :bacon
1825
- set.recognize(request)
1826
- flunk 'Should have raised NotImplemented'
1827
- rescue ActionController::NotImplemented => e
1828
- assert_equal [:get, :post, :put, :delete], e.allowed_methods
738
+ def host_with_port
739
+ (subdomains * '.') + '.' + domain
1829
740
  end
741
+ end
1830
742
 
1831
- request.path = "/people/5"
1832
- request.method = :get
1833
- assert_nothing_raised { set.recognize(request) }
1834
- assert_equal("show", request.path_parameters[:action])
1835
- assert_equal("5", request.path_parameters[:id])
743
+ class LegacyRouteSetTests < Test::Unit::TestCase
744
+ attr_reader :rs
1836
745
 
1837
- request.method = :put
1838
- assert_nothing_raised { set.recognize(request) }
1839
- assert_equal("update", request.path_parameters[:action])
1840
- assert_equal("5", request.path_parameters[:id])
746
+ def setup
747
+ # These tests assume optimisation is on, so re-enable it.
748
+ ActionController::Base.optimise_named_routes = true
1841
749
 
1842
- request.method = :delete
1843
- assert_nothing_raised { set.recognize(request) }
1844
- assert_equal("destroy", request.path_parameters[:action])
1845
- assert_equal("5", request.path_parameters[:id])
750
+ @rs = ::ActionController::Routing::RouteSet.new
751
+ @rs.draw {|m| m.connect ':controller/:action/:id' }
1846
752
 
1847
- begin
1848
- request.method = :post
1849
- set.recognize(request)
1850
- flunk 'Should have raised MethodNotAllowed'
1851
- rescue ActionController::MethodNotAllowed => e
1852
- assert_equal [:get, :put, :delete], e.allowed_methods
753
+ ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed)
1853
754
  end
1854
755
 
1855
- ensure
1856
- Object.send(:remove_const, :PeopleController)
1857
- end
1858
-
1859
- def test_recognize_with_alias_in_conditions
1860
- Object.const_set(:PeopleController, Class.new)
756
+ def test_default_setup
757
+ assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
758
+ assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
759
+ assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
1861
760
 
1862
- set.draw do |map|
1863
- map.people "/people", :controller => 'people', :action => "index",
1864
- :conditions => { :method => :get }
1865
- map.root :people
1866
- end
761
+ assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
1867
762
 
1868
- request.path = "/people"
1869
- request.method = :get
1870
- assert_nothing_raised { set.recognize(request) }
1871
- assert_equal("people", request.path_parameters[:controller])
1872
- assert_equal("index", request.path_parameters[:action])
763
+ assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10)
1873
764
 
1874
- request.path = "/"
1875
- request.method = :get
1876
- assert_nothing_raised { set.recognize(request) }
1877
- assert_equal("people", request.path_parameters[:controller])
1878
- assert_equal("index", request.path_parameters[:action])
1879
- ensure
1880
- Object.send(:remove_const, :PeopleController)
1881
- end
1882
-
1883
- def test_typo_recognition
1884
- Object.const_set(:ArticlesController, Class.new)
1885
-
1886
- set.draw do |map|
1887
- map.connect 'articles/:year/:month/:day/:title',
1888
- :controller => 'articles', :action => 'permalink',
1889
- :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
1890
- end
1891
-
1892
- request.path = "/articles/2005/11/05/a-very-interesting-article"
1893
- request.method = :get
1894
- assert_nothing_raised { set.recognize(request) }
1895
- assert_equal("permalink", request.path_parameters[:action])
1896
- assert_equal("2005", request.path_parameters[:year])
1897
- assert_equal("11", request.path_parameters[:month])
1898
- assert_equal("05", request.path_parameters[:day])
1899
- assert_equal("a-very-interesting-article", request.path_parameters[:title])
1900
-
1901
- ensure
1902
- Object.send(:remove_const, :ArticlesController)
1903
- end
765
+ assert_equal '/admin/user/show', rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
766
+ assert_equal '/admin/user/list/10', rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'})
1904
767
 
1905
- def test_routing_traversal_does_not_load_extra_classes
1906
- assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
1907
- set.draw do |map|
1908
- map.connect '/profile', :controller => 'profile'
768
+ assert_equal '/admin/stuff', rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
769
+ assert_equal '/stuff', rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
1909
770
  end
1910
771
 
1911
- request.path = '/profile'
1912
-
1913
- set.recognize(request) rescue nil
1914
-
1915
- assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
1916
- end
772
+ def test_ignores_leading_slash
773
+ @rs.draw {|m| m.connect '/:controller/:action/:id'}
774
+ test_default_setup
775
+ end
1917
776
 
1918
- def test_recognize_with_conditions_and_format
1919
- Object.const_set(:PeopleController, Class.new)
777
+ def test_time_recognition
778
+ # We create many routes to make situation more realistic
779
+ @rs = ::ActionController::Routing::RouteSet.new
780
+ @rs.draw { |map|
781
+ map.frontpage '', :controller => 'search', :action => 'new'
782
+ map.resources :videos do |video|
783
+ video.resources :comments
784
+ video.resource :file, :controller => 'video_file'
785
+ video.resource :share, :controller => 'video_shares'
786
+ video.resource :abuse, :controller => 'video_abuses'
787
+ end
788
+ map.resources :abuses, :controller => 'video_abuses'
789
+ map.resources :video_uploads
790
+ map.resources :video_visits
1920
791
 
1921
- set.draw do |map|
1922
- map.with_options(:controller => "people") do |people|
1923
- people.person "/people/:id", :action => "show", :conditions => { :method => :get }
1924
- people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
1925
- people.connect "/people/:id.:_format", :action => "show", :conditions => { :method => :get }
792
+ map.resources :users do |user|
793
+ user.resource :settings
794
+ user.resources :videos
795
+ end
796
+ map.resources :channels do |channel|
797
+ channel.resources :videos, :controller => 'channel_videos'
798
+ end
799
+ map.resource :session
800
+ map.resource :lost_password
801
+ map.search 'search', :controller => 'search'
802
+ map.resources :pages
803
+ map.connect ':controller/:action/:id'
804
+ }
805
+ n = 1000
806
+ if RunTimeTests
807
+ GC.start
808
+ rectime = Benchmark.realtime do
809
+ n.times do
810
+ rs.recognize_path("/videos/1234567", {:method => :get})
811
+ rs.recognize_path("/videos/1234567/abuse", {:method => :get})
812
+ rs.recognize_path("/users/1234567/settings", {:method => :get})
813
+ rs.recognize_path("/channels/1234567", {:method => :get})
814
+ rs.recognize_path("/session/new", {:method => :get})
815
+ rs.recognize_path("/admin/user/show/10", {:method => :get})
816
+ end
817
+ end
818
+ puts "\n\nRecognition (#{rs.routes.size} routes):"
819
+ per_url = rectime / (n * 6)
820
+ puts "#{per_url * 1000} ms/url"
821
+ puts "#{1 / per_url} url/s\n\n"
1926
822
  end
1927
823
  end
1928
824
 
1929
- request.path = "/people/5"
1930
- request.method = :get
1931
- assert_nothing_raised { set.recognize(request) }
1932
- assert_equal("show", request.path_parameters[:action])
1933
- assert_equal("5", request.path_parameters[:id])
1934
-
1935
- request.method = :put
1936
- assert_nothing_raised { set.recognize(request) }
1937
- assert_equal("update", request.path_parameters[:action])
1938
-
1939
- request.path = "/people/5.png"
1940
- request.method = :get
1941
- assert_nothing_raised { set.recognize(request) }
1942
- assert_equal("show", request.path_parameters[:action])
1943
- assert_equal("5", request.path_parameters[:id])
1944
- assert_equal("png", request.path_parameters[:_format])
1945
- ensure
1946
- Object.send(:remove_const, :PeopleController)
1947
- end
825
+ def test_time_generation
826
+ n = 5000
827
+ if RunTimeTests
828
+ GC.start
829
+ pairs = [
830
+ [{:controller => 'content', :action => 'index'}, {:controller => 'content', :action => 'show'}],
831
+ [{:controller => 'content'}, {:controller => 'content', :action => 'index'}],
832
+ [{:controller => 'content', :action => 'list'}, {:controller => 'content', :action => 'index'}],
833
+ [{:controller => 'content', :action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}],
834
+ [{:controller => 'admin/user', :action => 'index'}, {:controller => 'admin/user', :action => 'show'}],
835
+ [{:controller => 'admin/user'}, {:controller => 'admin/user', :action => 'index'}],
836
+ [{:controller => 'admin/user', :action => 'list'}, {:controller => 'admin/user', :action => 'index'}],
837
+ [{:controller => 'admin/user', :action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}],
838
+ ]
839
+ p = nil
840
+ gentime = Benchmark.realtime do
841
+ n.times do
842
+ pairs.each {|(a, b)| rs.generate(a, b)}
843
+ end
844
+ end
1948
845
 
1949
- def test_generate_with_default_action
1950
- set.draw do |map|
1951
- map.connect "/people", :controller => "people"
1952
- map.connect "/people/list", :controller => "people", :action => "list"
846
+ puts "\n\nGeneration (RouteSet): (#{(n * 8)} urls)"
847
+ per_url = gentime / (n * 8)
848
+ puts "#{per_url * 1000} ms/url"
849
+ puts "#{1 / per_url} url/s\n\n"
850
+ end
1953
851
  end
1954
852
 
1955
- url = set.generate(:controller => "people", :action => "list")
1956
- assert_equal "/people/list", url
1957
- end
1958
-
1959
- def test_root_map
1960
- Object.const_set(:PeopleController, Class.new)
1961
-
1962
- set.draw { |map| map.root :controller => "people" }
1963
-
1964
- request.path = ""
1965
- request.method = :get
1966
- assert_nothing_raised { set.recognize(request) }
1967
- assert_equal("people", request.path_parameters[:controller])
1968
- assert_equal("index", request.path_parameters[:action])
1969
- ensure
1970
- Object.send(:remove_const, :PeopleController)
1971
- end
1972
-
1973
-
1974
- def test_namespace
1975
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
1976
-
1977
- set.draw do |map|
1978
-
1979
- map.namespace 'api' do |api|
1980
- api.route 'inventory', :controller => "products", :action => 'inventory'
853
+ def test_route_with_colon_first
854
+ rs.draw do |map|
855
+ map.connect '/:controller/:action/:id', :action => 'index', :id => nil
856
+ map.connect ':url', :controller => 'tiny_url', :action => 'translate'
1981
857
  end
1982
-
1983
858
  end
1984
859
 
1985
- request.path = "/api/inventory"
1986
- request.method = :get
1987
- assert_nothing_raised { set.recognize(request) }
1988
- assert_equal("api/products", request.path_parameters[:controller])
1989
- assert_equal("inventory", request.path_parameters[:action])
1990
- ensure
1991
- Object.send(:remove_const, :Api)
1992
- end
1993
-
1994
-
1995
- def test_namespaced_root_map
1996
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
1997
-
1998
- set.draw do |map|
1999
-
2000
- map.namespace 'api' do |api|
2001
- api.root :controller => "products"
860
+ def test_route_with_regexp_for_controller
861
+ rs.draw do |map|
862
+ map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/
863
+ map.connect ':controller/:action/:id'
2002
864
  end
2003
-
865
+ assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
866
+ rs.recognize_path("/admin/user/foo"))
867
+ assert_equal({:controller => "content", :action => "foo"}, rs.recognize_path("/content/foo"))
868
+ assert_equal '/admin/user/foo', rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index")
869
+ assert_equal '/content/foo', rs.generate(:controller => "content", :action => "foo")
2004
870
  end
2005
871
 
2006
- request.path = "/api"
2007
- request.method = :get
2008
- assert_nothing_raised { set.recognize(request) }
2009
- assert_equal("api/products", request.path_parameters[:controller])
2010
- assert_equal("index", request.path_parameters[:action])
2011
- ensure
2012
- Object.send(:remove_const, :Api)
2013
- end
2014
-
2015
- def test_namespace_with_path_prefix
2016
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
2017
-
2018
- set.draw do |map|
2019
-
2020
- map.namespace 'api', :path_prefix => 'prefix' do |api|
2021
- api.route 'inventory', :controller => "products", :action => 'inventory'
872
+ def test_route_with_regexp_and_dot
873
+ rs.draw do |map|
874
+ map.connect ':controller/:action/:file',
875
+ :controller => /admin|user/,
876
+ :action => /upload|download/,
877
+ :defaults => {:file => nil},
878
+ :requirements => {:file => %r{[^/]+(\.[^/]+)?}}
2022
879
  end
2023
-
880
+ # Without a file extension
881
+ assert_equal '/user/download/file',
882
+ rs.generate(:controller => "user", :action => "download", :file => "file")
883
+ assert_equal(
884
+ {:controller => "user", :action => "download", :file => "file"},
885
+ rs.recognize_path("/user/download/file"))
886
+
887
+ # Now, let's try a file with an extension, really a dot (.)
888
+ assert_equal '/user/download/file.jpg',
889
+ rs.generate(
890
+ :controller => "user", :action => "download", :file => "file.jpg")
891
+ assert_equal(
892
+ {:controller => "user", :action => "download", :file => "file.jpg"},
893
+ rs.recognize_path("/user/download/file.jpg"))
894
+ end
895
+
896
+ def test_basic_named_route
897
+ rs.add_named_route :home, '', :controller => 'content', :action => 'list'
898
+ x = setup_for_named_route
899
+ assert_equal("http://named.route.test/",
900
+ x.send(:home_url))
2024
901
  end
2025
902
 
2026
- request.path = "/prefix/inventory"
2027
- request.method = :get
2028
- assert_nothing_raised { set.recognize(request) }
2029
- assert_equal("api/products", request.path_parameters[:controller])
2030
- assert_equal("inventory", request.path_parameters[:action])
2031
- ensure
2032
- Object.send(:remove_const, :Api)
2033
- end
2034
-
2035
- def test_generate_finds_best_fit
2036
- set.draw do |map|
2037
- map.connect "/people", :controller => "people", :action => "index"
2038
- map.connect "/ws/people", :controller => "people", :action => "index", :ws => true
903
+ def test_basic_named_route_with_relative_url_root
904
+ rs.add_named_route :home, '', :controller => 'content', :action => 'list'
905
+ x = setup_for_named_route
906
+ ActionController::Base.relative_url_root = "/foo"
907
+ assert_equal("http://named.route.test/foo/",
908
+ x.send(:home_url))
909
+ assert_equal "/foo/", x.send(:home_path)
910
+ ActionController::Base.relative_url_root = nil
2039
911
  end
2040
912
 
2041
- url = set.generate(:controller => "people", :action => "index", :ws => true)
2042
- assert_equal "/ws/people", url
2043
- end
913
+ def test_named_route_with_option
914
+ rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page'
915
+ x = setup_for_named_route
916
+ assert_equal("http://named.route.test/page/new%20stuff",
917
+ x.send(:page_url, :title => 'new stuff'))
918
+ end
2044
919
 
2045
- def test_generate_changes_controller_module
2046
- set.draw { |map| map.connect ':controller/:action/:id' }
2047
- current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
2048
- url = set.generate({:controller => "foo/bar", :action => "baz", :id => 7}, current)
2049
- assert_equal "/foo/bar/baz/7", url
2050
- end
920
+ def test_named_route_with_default
921
+ rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage'
922
+ x = setup_for_named_route
923
+ assert_equal("http://named.route.test/page/AboutRails",
924
+ x.send(:page_url, :title => "AboutRails"))
2051
925
 
2052
- def test_id_is_not_impossibly_sticky
2053
- set.draw do |map|
2054
- map.connect 'foo/:number', :controller => "people", :action => "index"
2055
- map.connect ':controller/:action/:id'
2056
926
  end
2057
927
 
2058
- url = set.generate({:controller => "people", :action => "index", :number => 3},
2059
- {:controller => "people", :action => "index", :id => "21"})
2060
- assert_equal "/foo/3", url
2061
- end
2062
-
2063
- def test_id_is_sticky_when_it_ought_to_be
2064
- set.draw do |map|
2065
- map.connect ':controller/:id/:action'
928
+ def test_named_route_with_name_prefix
929
+ rs.add_named_route :page, 'page', :controller => 'content', :action => 'show_page', :name_prefix => 'my_'
930
+ x = setup_for_named_route
931
+ assert_equal("http://named.route.test/page",
932
+ x.send(:my_page_url))
2066
933
  end
2067
934
 
2068
- url = set.generate({:action => "destroy"}, {:controller => "people", :action => "show", :id => "7"})
2069
- assert_equal "/people/7/destroy", url
2070
- end
935
+ def test_named_route_with_path_prefix
936
+ rs.add_named_route :page, 'page', :controller => 'content', :action => 'show_page', :path_prefix => 'my'
937
+ x = setup_for_named_route
938
+ assert_equal("http://named.route.test/my/page",
939
+ x.send(:page_url))
940
+ end
2071
941
 
2072
- def test_use_static_path_when_possible
2073
- set.draw do |map|
2074
- map.connect 'about', :controller => "welcome", :action => "about"
2075
- map.connect ':controller/:action/:id'
942
+ def test_named_route_with_nested_controller
943
+ rs.add_named_route :users, 'admin/user', :controller => 'admin/user', :action => 'index'
944
+ x = setup_for_named_route
945
+ assert_equal("http://named.route.test/admin/user",
946
+ x.send(:users_url))
2076
947
  end
2077
948
 
2078
- url = set.generate({:controller => "welcome", :action => "about"},
2079
- {:controller => "welcome", :action => "get", :id => "7"})
2080
- assert_equal "/about", url
949
+ def test_optimised_named_route_call_never_uses_url_for
950
+ rs.add_named_route :users, 'admin/user', :controller => '/admin/user', :action => 'index'
951
+ rs.add_named_route :user, 'admin/user/:id', :controller=>'/admin/user', :action=>'show'
952
+ x = setup_for_named_route
953
+ x.expects(:url_for).never
954
+ x.send(:users_url)
955
+ x.send(:users_path)
956
+ x.send(:user_url, 2, :foo=>"bar")
957
+ x.send(:user_path, 3, :bar=>"foo")
958
+ end
959
+
960
+ def test_optimised_named_route_with_host
961
+ rs.add_named_route :pages, 'pages', :controller => 'content', :action => 'show_page', :host => 'foo.com'
962
+ x = setup_for_named_route
963
+ x.expects(:url_for).with(:host => 'foo.com', :only_path => false, :controller => 'content', :action => 'show_page', :use_route => :pages).once
964
+ x.send(:pages_url)
965
+ end
966
+
967
+ def setup_for_named_route
968
+ klass = Class.new(MockController)
969
+ rs.install_helpers(klass)
970
+ klass.new(rs)
971
+ end
972
+
973
+ def test_named_route_without_hash
974
+ rs.draw do |map|
975
+ map.normal ':controller/:action/:id'
976
+ end
977
+ end
978
+
979
+ def test_named_route_root
980
+ rs.draw do |map|
981
+ map.root :controller => "hello"
982
+ end
983
+ x = setup_for_named_route
984
+ assert_equal("http://named.route.test/", x.send(:root_url))
985
+ assert_equal("/", x.send(:root_path))
986
+ end
987
+
988
+ def test_named_route_with_regexps
989
+ rs.draw do |map|
990
+ map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show',
991
+ :year => /\d+/, :month => /\d+/, :day => /\d+/
992
+ map.connect ':controller/:action/:id'
993
+ end
994
+ x = setup_for_named_route
995
+ # assert_equal(
996
+ # {:controller => 'page', :action => 'show', :title => 'hi', :use_route => :article, :only_path => false},
997
+ # x.send(:article_url, :title => 'hi')
998
+ # )
999
+ assert_equal(
1000
+ "http://named.route.test/page/2005/6/10/hi",
1001
+ x.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
1002
+ )
1003
+ end
1004
+
1005
+ def test_changing_controller
1006
+ assert_equal '/admin/stuff/show/10', rs.generate(
1007
+ {:controller => 'stuff', :action => 'show', :id => 10},
1008
+ {:controller => 'admin/user', :action => 'index'}
1009
+ )
1010
+ end
1011
+
1012
+ def test_paths_escaped
1013
+ rs.draw do |map|
1014
+ map.path 'file/*path', :controller => 'content', :action => 'show_file'
1015
+ map.connect ':controller/:action/:id'
1016
+ end
1017
+
1018
+ # No + to space in URI escaping, only for query params.
1019
+ results = rs.recognize_path "/file/hello+world/how+are+you%3F"
1020
+ assert results, "Recognition should have succeeded"
1021
+ assert_equal ['hello+world', 'how+are+you?'], results[:path]
1022
+
1023
+ # Use %20 for space instead.
1024
+ results = rs.recognize_path "/file/hello%20world/how%20are%20you%3F"
1025
+ assert results, "Recognition should have succeeded"
1026
+ assert_equal ['hello world', 'how are you?'], results[:path]
1027
+
1028
+ results = rs.recognize_path "/file"
1029
+ assert results, "Recognition should have succeeded"
1030
+ assert_equal [], results[:path]
1031
+ end
1032
+
1033
+ def test_paths_slashes_unescaped_with_ordered_parameters
1034
+ rs.add_named_route :path, '/file/*path', :controller => 'content'
1035
+
1036
+ # No / to %2F in URI, only for query params.
1037
+ x = setup_for_named_route
1038
+ assert_equal("/file/hello/world", x.send(:path_path, 'hello/world'))
1039
+ end
1040
+
1041
+ def test_non_controllers_cannot_be_matched
1042
+ rs.draw do |map|
1043
+ map.connect ':controller/:action/:id'
1044
+ end
1045
+ assert_raises(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
1046
+ end
1047
+
1048
+ def test_paths_do_not_accept_defaults
1049
+ assert_raises(ActionController::RoutingError) do
1050
+ rs.draw do |map|
1051
+ map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default)
1052
+ map.connect ':controller/:action/:id'
1053
+ end
1054
+ end
1055
+
1056
+ rs.draw do |map|
1057
+ map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => []
1058
+ map.connect ':controller/:action/:id'
1059
+ end
1060
+ end
1061
+
1062
+ def test_should_list_options_diff_when_routing_requirements_dont_match
1063
+ rs.draw do |map|
1064
+ map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
1065
+ end
1066
+ exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") }
1067
+ assert_match /^post_url failed to generate/, exception.message
1068
+ from_match = exception.message.match(/from \{[^\}]+\}/).to_s
1069
+ assert_match /:bad_param=>"foo"/, from_match
1070
+ assert_match /:action=>"show"/, from_match
1071
+ assert_match /:controller=>"post"/, from_match
1072
+
1073
+ expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s
1074
+ assert_no_match /:bad_param=>"foo"/, expected_match
1075
+ assert_match /:action=>"show"/, expected_match
1076
+ assert_match /:controller=>"post"/, expected_match
1077
+
1078
+ diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s
1079
+ assert_match /:bad_param=>"foo"/, diff_match
1080
+ assert_no_match /:action=>"show"/, diff_match
1081
+ assert_no_match /:controller=>"post"/, diff_match
1082
+ end
1083
+
1084
+ # this specifies the case where your formerly would get a very confusing error message with an empty diff
1085
+ def test_should_have_better_error_message_when_options_diff_is_empty
1086
+ rs.draw do |map|
1087
+ map.content '/content/:query', :controller => 'content', :action => 'show'
1088
+ end
1089
+
1090
+ exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'content', :action => 'show', :use_route => "content") }
1091
+ assert_match %r[:action=>"show"], exception.message
1092
+ assert_match %r[:controller=>"content"], exception.message
1093
+ assert_match %r[you may have ambiguous routes, or you may need to supply additional parameters for this route], exception.message
1094
+ assert_match %r[content_url has the following required parameters: \["content", :query\] - are they all satisfied?], exception.message
1095
+ end
1096
+
1097
+ def test_dynamic_path_allowed
1098
+ rs.draw do |map|
1099
+ map.connect '*path', :controller => 'content', :action => 'show_file'
1100
+ end
1101
+
1102
+ assert_equal '/pages/boo', rs.generate(:controller => 'content', :action => 'show_file', :path => %w(pages boo))
1103
+ end
1104
+
1105
+ def test_dynamic_recall_paths_allowed
1106
+ rs.draw do |map|
1107
+ map.connect '*path', :controller => 'content', :action => 'show_file'
1108
+ end
1109
+
1110
+ recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo))
1111
+ assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path)
1112
+ end
1113
+
1114
+ def test_backwards
1115
+ rs.draw do |map|
1116
+ map.connect 'page/:id/:action', :controller => 'pages', :action => 'show'
1117
+ map.connect ':controller/:action/:id'
1118
+ end
1119
+
1120
+ assert_equal '/page/20', rs.generate({:id => 20}, {:controller => 'pages', :action => 'show'})
1121
+ assert_equal '/page/20', rs.generate(:controller => 'pages', :id => 20, :action => 'show')
1122
+ assert_equal '/pages/boo', rs.generate(:controller => 'pages', :action => 'boo')
1123
+ end
1124
+
1125
+ def test_route_with_fixnum_default
1126
+ rs.draw do |map|
1127
+ map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
1128
+ map.connect ':controller/:action/:id'
1129
+ end
1130
+
1131
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page')
1132
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => 1)
1133
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => '1')
1134
+ assert_equal '/page/10', rs.generate(:controller => 'content', :action => 'show_page', :id => 10)
1135
+
1136
+ assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page"))
1137
+ assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
1138
+ assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
1139
+ end
1140
+
1141
+ # For newer revision
1142
+ def test_route_with_text_default
1143
+ rs.draw do |map|
1144
+ map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
1145
+ map.connect ':controller/:action/:id'
1146
+ end
1147
+
1148
+ assert_equal '/page/foo', rs.generate(:controller => 'content', :action => 'show_page', :id => 'foo')
1149
+ assert_equal({:controller => "content", :action => 'show_page', :id => 'foo'}, rs.recognize_path("/page/foo"))
1150
+
1151
+ token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in russian
1152
+ escaped_token = CGI::escape(token)
1153
+
1154
+ assert_equal '/page/' + escaped_token, rs.generate(:controller => 'content', :action => 'show_page', :id => token)
1155
+ assert_equal({:controller => "content", :action => 'show_page', :id => token}, rs.recognize_path("/page/#{escaped_token}"))
1156
+ end
1157
+
1158
+ def test_action_expiry
1159
+ assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
1160
+ end
1161
+
1162
+ def test_recognition_with_uppercase_controller_name
1163
+ assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content"))
1164
+ assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list"))
1165
+ assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10"))
1166
+
1167
+ # these used to work, before the routes rewrite, but support for this was pulled in the new version...
1168
+ #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed"))
1169
+ #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed"))
1170
+ end
1171
+
1172
+ def test_requirement_should_prevent_optional_id
1173
+ rs.draw do |map|
1174
+ map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
1175
+ end
1176
+
1177
+ assert_equal '/post/10', rs.generate(:controller => 'post', :action => 'show', :id => 10)
1178
+
1179
+ assert_raises ActionController::RoutingError do
1180
+ rs.generate(:controller => 'post', :action => 'show')
1181
+ end
1182
+ end
1183
+
1184
+ def test_both_requirement_and_optional
1185
+ rs.draw do |map|
1186
+ map.blog('test/:year', :controller => 'post', :action => 'show',
1187
+ :defaults => { :year => nil },
1188
+ :requirements => { :year => /\d{4}/ }
1189
+ )
1190
+ map.connect ':controller/:action/:id'
1191
+ end
1192
+
1193
+ assert_equal '/test', rs.generate(:controller => 'post', :action => 'show')
1194
+ assert_equal '/test', rs.generate(:controller => 'post', :action => 'show', :year => nil)
1195
+
1196
+ x = setup_for_named_route
1197
+ assert_equal("http://named.route.test/test",
1198
+ x.send(:blog_url))
1199
+ end
1200
+
1201
+ def test_set_to_nil_forgets
1202
+ rs.draw do |map|
1203
+ map.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil
1204
+ map.connect ':controller/:action/:id'
1205
+ end
1206
+
1207
+ assert_equal '/pages/2005',
1208
+ rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005)
1209
+ assert_equal '/pages/2005/6',
1210
+ rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6)
1211
+ assert_equal '/pages/2005/6/12',
1212
+ rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12)
1213
+
1214
+ assert_equal '/pages/2005/6/4',
1215
+ rs.generate({:day => 4}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
1216
+
1217
+ assert_equal '/pages/2005/6',
1218
+ rs.generate({:day => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
1219
+
1220
+ assert_equal '/pages/2005',
1221
+ rs.generate({:day => nil, :month => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
1222
+ end
1223
+
1224
+ def test_url_with_no_action_specified
1225
+ rs.draw do |map|
1226
+ map.connect '', :controller => 'content'
1227
+ map.connect ':controller/:action/:id'
1228
+ end
1229
+
1230
+ assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
1231
+ assert_equal '/', rs.generate(:controller => 'content')
1232
+ end
1233
+
1234
+ def test_named_url_with_no_action_specified
1235
+ rs.draw do |map|
1236
+ map.home '', :controller => 'content'
1237
+ map.connect ':controller/:action/:id'
1238
+ end
1239
+
1240
+ assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
1241
+ assert_equal '/', rs.generate(:controller => 'content')
1242
+
1243
+ x = setup_for_named_route
1244
+ assert_equal("http://named.route.test/",
1245
+ x.send(:home_url))
1246
+ end
1247
+
1248
+ def test_url_generated_when_forgetting_action
1249
+ [{:controller => 'content', :action => 'index'}, {:controller => 'content'}].each do |hash|
1250
+ rs.draw do |map|
1251
+ map.home '', hash
1252
+ map.connect ':controller/:action/:id'
1253
+ end
1254
+ assert_equal '/', rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'})
1255
+ assert_equal '/', rs.generate({:controller => 'content'})
1256
+ assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
1257
+ end
1258
+ end
1259
+
1260
+ def test_named_route_method
1261
+ rs.draw do |map|
1262
+ map.categories 'categories', :controller => 'content', :action => 'categories'
1263
+ map.connect ':controller/:action/:id'
1264
+ end
1265
+
1266
+ assert_equal '/categories', rs.generate(:controller => 'content', :action => 'categories')
1267
+ assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
1268
+ end
1269
+
1270
+ def test_named_routes_array
1271
+ test_named_route_method
1272
+ assert_equal [:categories], rs.named_routes.names
1273
+ end
1274
+
1275
+ def test_nil_defaults
1276
+ rs.draw do |map|
1277
+ map.connect 'journal',
1278
+ :controller => 'content',
1279
+ :action => 'list_journal',
1280
+ :date => nil, :user_id => nil
1281
+ map.connect ':controller/:action/:id'
1282
+ end
1283
+
1284
+ assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil)
1285
+ end
1286
+
1287
+ def setup_request_method_routes_for(method)
1288
+ @request = ActionController::TestRequest.new
1289
+ @request.env["REQUEST_METHOD"] = method
1290
+ @request.request_uri = "/match"
1291
+
1292
+ rs.draw do |r|
1293
+ r.connect '/match', :controller => 'books', :action => 'get', :conditions => { :method => :get }
1294
+ r.connect '/match', :controller => 'books', :action => 'post', :conditions => { :method => :post }
1295
+ r.connect '/match', :controller => 'books', :action => 'put', :conditions => { :method => :put }
1296
+ r.connect '/match', :controller => 'books', :action => 'delete', :conditions => { :method => :delete }
1297
+ end
1298
+ end
1299
+
1300
+ %w(GET POST PUT DELETE).each do |request_method|
1301
+ define_method("test_request_method_recognized_with_#{request_method}") do
1302
+ begin
1303
+ Object.const_set(:BooksController, Class.new(ActionController::Base))
1304
+
1305
+ setup_request_method_routes_for(request_method)
1306
+
1307
+ assert_nothing_raised { rs.recognize(@request) }
1308
+ assert_equal request_method.downcase, @request.path_parameters[:action]
1309
+ ensure
1310
+ Object.send(:remove_const, :BooksController) rescue nil
1311
+ end
1312
+ end
1313
+ end
1314
+
1315
+ def test_recognize_array_of_methods
1316
+ Object.const_set(:BooksController, Class.new(ActionController::Base))
1317
+ rs.draw do |r|
1318
+ r.connect '/match', :controller => 'books', :action => 'get_or_post', :conditions => { :method => [:get, :post] }
1319
+ r.connect '/match', :controller => 'books', :action => 'not_get_or_post'
1320
+ end
1321
+
1322
+ @request = ActionController::TestRequest.new
1323
+ @request.env["REQUEST_METHOD"] = 'POST'
1324
+ @request.request_uri = "/match"
1325
+ assert_nothing_raised { rs.recognize(@request) }
1326
+ assert_equal 'get_or_post', @request.path_parameters[:action]
1327
+
1328
+ # have to recreate or else the RouteSet uses a cached version:
1329
+ @request = ActionController::TestRequest.new
1330
+ @request.env["REQUEST_METHOD"] = 'PUT'
1331
+ @request.request_uri = "/match"
1332
+ assert_nothing_raised { rs.recognize(@request) }
1333
+ assert_equal 'not_get_or_post', @request.path_parameters[:action]
1334
+ ensure
1335
+ Object.send(:remove_const, :BooksController) rescue nil
1336
+ end
1337
+
1338
+ def test_subpath_recognized
1339
+ Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
1340
+
1341
+ rs.draw do |r|
1342
+ r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
1343
+ r.connect '/items/:id/:action', :controller => 'subpath_books'
1344
+ r.connect '/posts/new/:action', :controller => 'subpath_books'
1345
+ r.connect '/posts/:id', :controller => 'subpath_books', :action => "show"
1346
+ end
1347
+
1348
+ hash = rs.recognize_path "/books/17/edit"
1349
+ assert_not_nil hash
1350
+ assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]]
1351
+
1352
+ hash = rs.recognize_path "/items/3/complete"
1353
+ assert_not_nil hash
1354
+ assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]]
1355
+
1356
+ hash = rs.recognize_path "/posts/new/preview"
1357
+ assert_not_nil hash
1358
+ assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]]
1359
+
1360
+ hash = rs.recognize_path "/posts/7"
1361
+ assert_not_nil hash
1362
+ assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
1363
+ ensure
1364
+ Object.send(:remove_const, :SubpathBooksController) rescue nil
1365
+ end
1366
+
1367
+ def test_subpath_generated
1368
+ Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
1369
+
1370
+ rs.draw do |r|
1371
+ r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
1372
+ r.connect '/items/:id/:action', :controller => 'subpath_books'
1373
+ r.connect '/posts/new/:action', :controller => 'subpath_books'
1374
+ end
1375
+
1376
+ assert_equal "/books/7/edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit")
1377
+ assert_equal "/items/15/complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete")
1378
+ assert_equal "/posts/new/preview", rs.generate(:controller => "subpath_books", :action => "preview")
1379
+ ensure
1380
+ Object.send(:remove_const, :SubpathBooksController) rescue nil
1381
+ end
1382
+
1383
+ def test_failed_requirements_raises_exception_with_violated_requirements
1384
+ rs.draw do |r|
1385
+ r.foo_with_requirement 'foos/:id', :controller=>'foos', :requirements=>{:id=>/\d+/}
1386
+ end
1387
+
1388
+ x = setup_for_named_route
1389
+ assert_raises(ActionController::RoutingError) do
1390
+ x.send(:foo_with_requirement_url, "I am Against the requirements")
1391
+ end
1392
+ end
1393
+
1394
+ def test_routes_changed_correctly_after_clear
1395
+ ActionController::Base.optimise_named_routes = true
1396
+ rs = ::ActionController::Routing::RouteSet.new
1397
+ rs.draw do |r|
1398
+ r.connect 'ca', :controller => 'ca', :action => "aa"
1399
+ r.connect 'cb', :controller => 'cb', :action => "ab"
1400
+ r.connect 'cc', :controller => 'cc', :action => "ac"
1401
+ r.connect ':controller/:action/:id'
1402
+ r.connect ':controller/:action/:id.:format'
1403
+ end
1404
+
1405
+ hash = rs.recognize_path "/cc"
1406
+
1407
+ assert_not_nil hash
1408
+ assert_equal %w(cc ac), [hash[:controller], hash[:action]]
1409
+
1410
+ rs.draw do |r|
1411
+ r.connect 'cb', :controller => 'cb', :action => "ab"
1412
+ r.connect 'cc', :controller => 'cc', :action => "ac"
1413
+ r.connect ':controller/:action/:id'
1414
+ r.connect ':controller/:action/:id.:format'
1415
+ end
1416
+
1417
+ hash = rs.recognize_path "/cc"
1418
+
1419
+ assert_not_nil hash
1420
+ assert_equal %w(cc ac), [hash[:controller], hash[:action]]
1421
+
1422
+ end
2081
1423
  end
2082
1424
 
2083
- def test_generate
2084
- set.draw { |map| map.connect ':controller/:action/:id' }
1425
+ class RouteTest < Test::Unit::TestCase
1426
+ def setup
1427
+ @route = ROUTING::Route.new
1428
+ end
1429
+
1430
+ def slash_segment(is_optional = false)
1431
+ ROUTING::DividerSegment.new('/', :optional => is_optional)
1432
+ end
1433
+
1434
+ def default_route
1435
+ unless defined?(@default_route)
1436
+ segments = []
1437
+ segments << ROUTING::StaticSegment.new('/', :raw => true)
1438
+ segments << ROUTING::DynamicSegment.new(:controller)
1439
+ segments << slash_segment(:optional)
1440
+ segments << ROUTING::DynamicSegment.new(:action, :default => 'index', :optional => true)
1441
+ segments << slash_segment(:optional)
1442
+ segments << ROUTING::DynamicSegment.new(:id, :optional => true)
1443
+ segments << slash_segment(:optional)
1444
+ @default_route = ROUTING::Route.new(segments).freeze
1445
+ end
1446
+ @default_route
1447
+ end
1448
+
1449
+ def test_default_route_recognition
1450
+ expected = {:controller => 'accounts', :action => 'show', :id => '10'}
1451
+ assert_equal expected, default_route.recognize('/accounts/show/10')
1452
+ assert_equal expected, default_route.recognize('/accounts/show/10/')
1453
+
1454
+ expected[:id] = 'jamis'
1455
+ assert_equal expected, default_route.recognize('/accounts/show/jamis/')
1456
+
1457
+ expected.delete :id
1458
+ assert_equal expected, default_route.recognize('/accounts/show')
1459
+ assert_equal expected, default_route.recognize('/accounts/show/')
1460
+
1461
+ expected[:action] = 'index'
1462
+ assert_equal expected, default_route.recognize('/accounts/')
1463
+ assert_equal expected, default_route.recognize('/accounts')
1464
+
1465
+ assert_equal nil, default_route.recognize('/')
1466
+ assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free')
1467
+ end
1468
+
1469
+ def test_default_route_should_omit_default_action
1470
+ o = {:controller => 'accounts', :action => 'index'}
1471
+ assert_equal '/accounts', default_route.generate(o, o, {})
1472
+ end
1473
+
1474
+ def test_default_route_should_include_default_action_when_id_present
1475
+ o = {:controller => 'accounts', :action => 'index', :id => '20'}
1476
+ assert_equal '/accounts/index/20', default_route.generate(o, o, {})
1477
+ end
1478
+
1479
+ def test_default_route_should_work_with_action_but_no_id
1480
+ o = {:controller => 'accounts', :action => 'list_all'}
1481
+ assert_equal '/accounts/list_all', default_route.generate(o, o, {})
1482
+ end
1483
+
1484
+ def test_default_route_should_uri_escape_pluses
1485
+ expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' }
1486
+ assert_equal expected, default_route.recognize('/accounts/show/hello world')
1487
+ assert_equal expected, default_route.recognize('/accounts/show/hello%20world')
1488
+ assert_equal '/accounts/show/hello%20world', default_route.generate(expected, expected, {})
1489
+
1490
+ expected[:id] = 'hello+world'
1491
+ assert_equal expected, default_route.recognize('/accounts/show/hello+world')
1492
+ assert_equal expected, default_route.recognize('/accounts/show/hello%2Bworld')
1493
+ assert_equal '/accounts/show/hello+world', default_route.generate(expected, expected, {})
1494
+ end
1495
+
1496
+ def test_matches_controller_and_action
1497
+ # requirement_for should only be called for the action and controller _once_
1498
+ @route.expects(:requirement_for).with(:controller).times(1).returns('pages')
1499
+ @route.expects(:requirement_for).with(:action).times(1).returns('show')
1500
+
1501
+ @route.requirements = {:controller => 'pages', :action => 'show'}
1502
+ assert @route.matches_controller_and_action?('pages', 'show')
1503
+ assert !@route.matches_controller_and_action?('not_pages', 'show')
1504
+ assert !@route.matches_controller_and_action?('pages', 'not_show')
1505
+ end
1506
+
1507
+ def test_parameter_shell
1508
+ page_url = ROUTING::Route.new
1509
+ page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/}
1510
+ assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell)
1511
+ end
1512
+
1513
+ def test_defaults
1514
+ route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html"
1515
+ assert_equal(
1516
+ { :controller => "users", :action => "show", :format => "html" },
1517
+ route.defaults)
1518
+ end
1519
+
1520
+ def test_builder_complains_without_controller
1521
+ assert_raises(ArgumentError) do
1522
+ ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index"
1523
+ end
1524
+ end
1525
+
1526
+ def test_significant_keys_for_default_route
1527
+ keys = default_route.significant_keys.sort_by {|k| k.to_s }
1528
+ assert_equal [:action, :controller, :id], keys
1529
+ end
1530
+
1531
+ def test_significant_keys
1532
+ segments = []
1533
+ segments << ROUTING::StaticSegment.new('/', :raw => true)
1534
+ segments << ROUTING::StaticSegment.new('user')
1535
+ segments << ROUTING::StaticSegment.new('/', :raw => true, :optional => true)
1536
+ segments << ROUTING::DynamicSegment.new(:user)
1537
+ segments << ROUTING::StaticSegment.new('/', :raw => true, :optional => true)
1538
+
1539
+ requirements = {:controller => 'users', :action => 'show'}
1540
+
1541
+ user_url = ROUTING::Route.new(segments, requirements)
1542
+ keys = user_url.significant_keys.sort_by { |k| k.to_s }
1543
+ assert_equal [:action, :controller, :user], keys
1544
+ end
1545
+
1546
+ def test_build_empty_query_string
1547
+ assert_equal '', @route.build_query_string({})
1548
+ end
1549
+
1550
+ def test_build_query_string_with_nil_value
1551
+ assert_equal '', @route.build_query_string({:x => nil})
1552
+ end
1553
+
1554
+ def test_simple_build_query_string
1555
+ assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2'))
1556
+ end
1557
+
1558
+ def test_convert_ints_build_query_string
1559
+ assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2))
1560
+ end
1561
+
1562
+ def test_escape_spaces_build_query_string
1563
+ assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world'))
1564
+ end
1565
+
1566
+ def test_expand_array_build_query_string
1567
+ assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2]))
1568
+ end
1569
+
1570
+ def test_escape_spaces_build_query_string_selected_keys
1571
+ assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x]))
1572
+ end
1573
+
1574
+ private
1575
+ def order_query_string(qs)
1576
+ '?' + qs[1..-1].split('&').sort.join('&')
1577
+ end
1578
+ end
1579
+
1580
+ class RouteSetTest < Test::Unit::TestCase
1581
+ def set
1582
+ @set ||= ROUTING::RouteSet.new
1583
+ end
1584
+
1585
+ def request
1586
+ @request ||= MockRequest.new(:host => "named.routes.test", :method => :get)
1587
+ end
1588
+
1589
+ def test_generate_extras
1590
+ set.draw { |m| m.connect ':controller/:action/:id' }
1591
+ path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1592
+ assert_equal "/foo/bar/15", path
1593
+ assert_equal %w(that this), extras.map(&:to_s).sort
1594
+ end
1595
+
1596
+ def test_extra_keys
1597
+ set.draw { |m| m.connect ':controller/:action/:id' }
1598
+ extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1599
+ assert_equal %w(that this), extras.map(&:to_s).sort
1600
+ end
1601
+
1602
+ def test_generate_extras_not_first
1603
+ set.draw do |map|
1604
+ map.connect ':controller/:action/:id.:format'
1605
+ map.connect ':controller/:action/:id'
1606
+ end
1607
+ path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1608
+ assert_equal "/foo/bar/15", path
1609
+ assert_equal %w(that this), extras.map(&:to_s).sort
1610
+ end
1611
+
1612
+ def test_generate_not_first
1613
+ set.draw do |map|
1614
+ map.connect ':controller/:action/:id.:format'
1615
+ map.connect ':controller/:action/:id'
1616
+ end
1617
+ assert_equal "/foo/bar/15?this=hello", set.generate(:controller => "foo", :action => "bar", :id => 15, :this => "hello")
1618
+ end
1619
+
1620
+ def test_extra_keys_not_first
1621
+ set.draw do |map|
1622
+ map.connect ':controller/:action/:id.:format'
1623
+ map.connect ':controller/:action/:id'
1624
+ end
1625
+ extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1626
+ assert_equal %w(that this), extras.map(&:to_s).sort
1627
+ end
1628
+
1629
+ def test_draw
1630
+ assert_equal 0, set.routes.size
1631
+ set.draw do |map|
1632
+ map.connect '/hello/world', :controller => 'a', :action => 'b'
1633
+ end
1634
+ assert_equal 1, set.routes.size
1635
+ end
1636
+
1637
+ def test_named_draw
1638
+ assert_equal 0, set.routes.size
1639
+ set.draw do |map|
1640
+ map.hello '/hello/world', :controller => 'a', :action => 'b'
1641
+ end
1642
+ assert_equal 1, set.routes.size
1643
+ assert_equal set.routes.first, set.named_routes[:hello]
1644
+ end
1645
+
1646
+ def test_later_named_routes_take_precedence
1647
+ set.draw do |map|
1648
+ map.hello '/hello/world', :controller => 'a', :action => 'b'
1649
+ map.hello '/hello', :controller => 'a', :action => 'b'
1650
+ end
1651
+ assert_equal set.routes.last, set.named_routes[:hello]
1652
+ end
1653
+
1654
+ def setup_named_route_test
1655
+ set.draw do |map|
1656
+ map.show '/people/:id', :controller => 'people', :action => 'show'
1657
+ map.index '/people', :controller => 'people', :action => 'index'
1658
+ map.multi '/people/go/:foo/:bar/joe/:id', :controller => 'people', :action => 'multi'
1659
+ map.users '/admin/users', :controller => 'admin/users', :action => 'index'
1660
+ end
1661
+
1662
+ klass = Class.new(MockController)
1663
+ set.install_helpers(klass)
1664
+ klass.new(set)
1665
+ end
1666
+
1667
+ def test_named_route_hash_access_method
1668
+ controller = setup_named_route_test
1669
+
1670
+ assert_equal(
1671
+ { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => false },
1672
+ controller.send(:hash_for_show_url, :id => 5))
1673
+
1674
+ assert_equal(
1675
+ { :controller => 'people', :action => 'index', :use_route => :index, :only_path => false },
1676
+ controller.send(:hash_for_index_url))
1677
+
1678
+ assert_equal(
1679
+ { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => true },
1680
+ controller.send(:hash_for_show_path, :id => 5)
1681
+ )
1682
+ end
1683
+
1684
+ def test_named_route_url_method
1685
+ controller = setup_named_route_test
1686
+
1687
+ assert_equal "http://named.route.test/people/5", controller.send(:show_url, :id => 5)
1688
+ assert_equal "/people/5", controller.send(:show_path, :id => 5)
1689
+
1690
+ assert_equal "http://named.route.test/people", controller.send(:index_url)
1691
+ assert_equal "/people", controller.send(:index_path)
1692
+
1693
+ assert_equal "http://named.route.test/admin/users", controller.send(:users_url)
1694
+ assert_equal '/admin/users', controller.send(:users_path)
1695
+ assert_equal '/admin/users', set.generate(controller.send(:hash_for_users_url), {:controller => 'users', :action => 'index'})
1696
+ end
1697
+
1698
+ def test_named_route_url_method_with_anchor
1699
+ controller = setup_named_route_test
1700
+
1701
+ assert_equal "http://named.route.test/people/5#location", controller.send(:show_url, :id => 5, :anchor => 'location')
1702
+ assert_equal "/people/5#location", controller.send(:show_path, :id => 5, :anchor => 'location')
1703
+
1704
+ assert_equal "http://named.route.test/people#location", controller.send(:index_url, :anchor => 'location')
1705
+ assert_equal "/people#location", controller.send(:index_path, :anchor => 'location')
1706
+
1707
+ assert_equal "http://named.route.test/admin/users#location", controller.send(:users_url, :anchor => 'location')
1708
+ assert_equal '/admin/users#location', controller.send(:users_path, :anchor => 'location')
1709
+
1710
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5#location",
1711
+ controller.send(:multi_url, 7, "hello", 5, :anchor => 'location')
1712
+
1713
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar#location",
1714
+ controller.send(:multi_url, 7, "hello", 5, :baz => "bar", :anchor => 'location')
1715
+
1716
+ assert_equal "http://named.route.test/people?baz=bar#location",
1717
+ controller.send(:index_url, :baz => "bar", :anchor => 'location')
1718
+ end
1719
+
1720
+ def test_named_route_url_method_with_port
1721
+ controller = setup_named_route_test
1722
+ assert_equal "http://named.route.test:8080/people/5", controller.send(:show_url, 5, :port=>8080)
1723
+ end
1724
+
1725
+ def test_named_route_url_method_with_host
1726
+ controller = setup_named_route_test
1727
+ assert_equal "http://some.example.com/people/5", controller.send(:show_url, 5, :host=>"some.example.com")
1728
+ end
1729
+
1730
+ def test_named_route_url_method_with_protocol
1731
+ controller = setup_named_route_test
1732
+ assert_equal "https://named.route.test/people/5", controller.send(:show_url, 5, :protocol => "https")
1733
+ end
1734
+
1735
+ def test_named_route_url_method_with_ordered_parameters
1736
+ controller = setup_named_route_test
1737
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5",
1738
+ controller.send(:multi_url, 7, "hello", 5)
1739
+ end
1740
+
1741
+ def test_named_route_url_method_with_ordered_parameters_and_hash
1742
+ controller = setup_named_route_test
1743
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5?baz=bar",
1744
+ controller.send(:multi_url, 7, "hello", 5, :baz => "bar")
1745
+ end
1746
+
1747
+ def test_named_route_url_method_with_ordered_parameters_and_empty_hash
1748
+ controller = setup_named_route_test
1749
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5",
1750
+ controller.send(:multi_url, 7, "hello", 5, {})
1751
+ end
1752
+
1753
+ def test_named_route_url_method_with_no_positional_arguments
1754
+ controller = setup_named_route_test
1755
+ assert_equal "http://named.route.test/people?baz=bar",
1756
+ controller.send(:index_url, :baz => "bar")
1757
+ end
1758
+
1759
+ def test_draw_default_route
1760
+ ActionController::Routing.with_controllers(['users']) do
1761
+ set.draw do |map|
1762
+ map.connect '/:controller/:action/:id'
1763
+ end
1764
+
1765
+ assert_equal 1, set.routes.size
1766
+ route = set.routes.first
1767
+
1768
+ assert route.segments.last.optional?
1769
+
1770
+ assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10)
1771
+ assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10)
1772
+
1773
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
1774
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
1775
+ end
1776
+ end
1777
+
1778
+ def test_draw_default_route_with_default_controller
1779
+ ActionController::Routing.with_controllers(['users']) do
1780
+ set.draw do |map|
1781
+ map.connect '/:controller/:action/:id', :controller => 'users'
1782
+ end
1783
+ assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/'))
1784
+ end
1785
+ end
1786
+
1787
+ def test_route_with_parameter_shell
1788
+ ActionController::Routing.with_controllers(['users', 'pages']) do
1789
+ set.draw do |map|
1790
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
1791
+ map.connect '/:controller/:action/:id'
1792
+ end
1793
+
1794
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
1795
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
1796
+ assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
1797
+
1798
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
1799
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
1800
+ end
1801
+ end
1802
+
1803
+ def test_route_requirements_with_anchor_chars_are_invalid
1804
+ assert_raises ArgumentError do
1805
+ set.draw do |map|
1806
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/
1807
+ end
1808
+ end
1809
+ assert_raises ArgumentError do
1810
+ set.draw do |map|
1811
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/
1812
+ end
1813
+ end
1814
+ assert_raises ArgumentError do
1815
+ set.draw do |map|
1816
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/
1817
+ end
1818
+ end
1819
+ assert_raises ArgumentError do
1820
+ set.draw do |map|
1821
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/
1822
+ end
1823
+ end
1824
+ assert_raises ArgumentError do
1825
+ set.draw do |map|
1826
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/
1827
+ end
1828
+ end
1829
+ assert_nothing_raised do
1830
+ set.draw do |map|
1831
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/
1832
+ end
1833
+ assert_raises ActionController::RoutingError do
1834
+ set.generate :controller => 'pages', :action => 'show', :id => 10
1835
+ end
1836
+ end
1837
+ end
1838
+
1839
+ def test_route_requirements_with_invalid_http_method_is_invalid
1840
+ assert_raises ArgumentError do
1841
+ set.draw do |map|
1842
+ map.connect 'valid/route', :controller => 'pages', :action => 'show', :conditions => {:method => :invalid}
1843
+ end
1844
+ end
1845
+ end
1846
+
1847
+ def test_route_requirements_with_head_method_condition_is_invalid
1848
+ assert_raises ArgumentError do
1849
+ set.draw do |map|
1850
+ map.connect 'valid/route', :controller => 'pages', :action => 'show', :conditions => {:method => :head}
1851
+ end
1852
+ end
1853
+ end
1854
+
1855
+ def test_non_path_route_requirements_match_all
1856
+ set.draw do |map|
1857
+ map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/
1858
+ end
1859
+ assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis')
1860
+ assert_raises ActionController::RoutingError do
1861
+ set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis')
1862
+ end
1863
+ assert_raises ActionController::RoutingError do
1864
+ set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david')
1865
+ end
1866
+ end
1867
+
1868
+ def test_recognize_with_encoded_id_and_regex
1869
+ set.draw do |map|
1870
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9\+]+/
1871
+ end
1872
+
1873
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
1874
+ assert_equal({:controller => 'pages', :action => 'show', :id => 'hello+world'}, set.recognize_path('/page/hello+world'))
1875
+ end
1876
+
1877
+ def test_recognize_with_conditions
1878
+ Object.const_set(:PeopleController, Class.new)
1879
+
1880
+ set.draw do |map|
1881
+ map.with_options(:controller => "people") do |people|
1882
+ people.people "/people", :action => "index", :conditions => { :method => :get }
1883
+ people.connect "/people", :action => "create", :conditions => { :method => :post }
1884
+ people.person "/people/:id", :action => "show", :conditions => { :method => :get }
1885
+ people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
1886
+ people.connect "/people/:id", :action => "destroy", :conditions => { :method => :delete }
1887
+ end
1888
+ end
1889
+
1890
+ request.path = "/people"
1891
+ request.method = :get
1892
+ assert_nothing_raised { set.recognize(request) }
1893
+ assert_equal("index", request.path_parameters[:action])
1894
+
1895
+ request.method = :post
1896
+ assert_nothing_raised { set.recognize(request) }
1897
+ assert_equal("create", request.path_parameters[:action])
1898
+
1899
+ request.method = :put
1900
+ assert_nothing_raised { set.recognize(request) }
1901
+ assert_equal("update", request.path_parameters[:action])
1902
+
1903
+ begin
1904
+ request.method = :bacon
1905
+ set.recognize(request)
1906
+ flunk 'Should have raised NotImplemented'
1907
+ rescue ActionController::NotImplemented => e
1908
+ assert_equal [:get, :post, :put, :delete], e.allowed_methods
1909
+ end
1910
+
1911
+ request.path = "/people/5"
1912
+ request.method = :get
1913
+ assert_nothing_raised { set.recognize(request) }
1914
+ assert_equal("show", request.path_parameters[:action])
1915
+ assert_equal("5", request.path_parameters[:id])
1916
+
1917
+ request.method = :put
1918
+ assert_nothing_raised { set.recognize(request) }
1919
+ assert_equal("update", request.path_parameters[:action])
1920
+ assert_equal("5", request.path_parameters[:id])
1921
+
1922
+ request.method = :delete
1923
+ assert_nothing_raised { set.recognize(request) }
1924
+ assert_equal("destroy", request.path_parameters[:action])
1925
+ assert_equal("5", request.path_parameters[:id])
1926
+
1927
+ begin
1928
+ request.method = :post
1929
+ set.recognize(request)
1930
+ flunk 'Should have raised MethodNotAllowed'
1931
+ rescue ActionController::MethodNotAllowed => e
1932
+ assert_equal [:get, :put, :delete], e.allowed_methods
1933
+ end
1934
+
1935
+ ensure
1936
+ Object.send(:remove_const, :PeopleController)
1937
+ end
1938
+
1939
+ def test_recognize_with_alias_in_conditions
1940
+ Object.const_set(:PeopleController, Class.new)
1941
+
1942
+ set.draw do |map|
1943
+ map.people "/people", :controller => 'people', :action => "index",
1944
+ :conditions => { :method => :get }
1945
+ map.root :people
1946
+ end
1947
+
1948
+ request.path = "/people"
1949
+ request.method = :get
1950
+ assert_nothing_raised { set.recognize(request) }
1951
+ assert_equal("people", request.path_parameters[:controller])
1952
+ assert_equal("index", request.path_parameters[:action])
2085
1953
 
2086
- args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
2087
- assert_equal "/foo/bar/7?x=y", set.generate(args)
2088
- assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
2089
- assert_equal [:x], set.extra_keys(args)
2090
- end
1954
+ request.path = "/"
1955
+ request.method = :get
1956
+ assert_nothing_raised { set.recognize(request) }
1957
+ assert_equal("people", request.path_parameters[:controller])
1958
+ assert_equal("index", request.path_parameters[:action])
1959
+ ensure
1960
+ Object.send(:remove_const, :PeopleController)
1961
+ end
1962
+
1963
+ def test_typo_recognition
1964
+ Object.const_set(:ArticlesController, Class.new)
1965
+
1966
+ set.draw do |map|
1967
+ map.connect 'articles/:year/:month/:day/:title',
1968
+ :controller => 'articles', :action => 'permalink',
1969
+ :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
1970
+ end
2091
1971
 
2092
- def test_named_routes_are_never_relative_to_modules
2093
- set.draw do |map|
2094
- map.connect "/connection/manage/:action", :controller => 'connection/manage'
2095
- map.connect "/connection/connection", :controller => "connection/connection"
2096
- map.family_connection "/connection", :controller => "connection"
1972
+ request.path = "/articles/2005/11/05/a-very-interesting-article"
1973
+ request.method = :get
1974
+ assert_nothing_raised { set.recognize(request) }
1975
+ assert_equal("permalink", request.path_parameters[:action])
1976
+ assert_equal("2005", request.path_parameters[:year])
1977
+ assert_equal("11", request.path_parameters[:month])
1978
+ assert_equal("05", request.path_parameters[:day])
1979
+ assert_equal("a-very-interesting-article", request.path_parameters[:title])
1980
+
1981
+ ensure
1982
+ Object.send(:remove_const, :ArticlesController)
2097
1983
  end
2098
1984
 
2099
- url = set.generate({:controller => "connection"}, {:controller => 'connection/manage'})
2100
- assert_equal "/connection/connection", url
1985
+ def test_routing_traversal_does_not_load_extra_classes
1986
+ assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
1987
+ set.draw do |map|
1988
+ map.connect '/profile', :controller => 'profile'
1989
+ end
1990
+
1991
+ request.path = '/profile'
2101
1992
 
2102
- url = set.generate({:use_route => :family_connection, :controller => "connection"}, {:controller => 'connection/manage'})
2103
- assert_equal "/connection", url
2104
- end
2105
-
2106
- def test_action_left_off_when_id_is_recalled
2107
- set.draw do |map|
2108
- map.connect ':controller/:action/:id'
1993
+ set.recognize(request) rescue nil
1994
+
1995
+ assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
2109
1996
  end
2110
- assert_equal '/post', set.generate(
2111
- {:controller => 'post', :action => 'index'},
2112
- {:controller => 'post', :action => 'show', :id => '10'}
2113
- )
2114
- end
2115
-
2116
- def test_query_params_will_be_shown_when_recalled
2117
- set.draw do |map|
2118
- map.connect 'show_post/:parameter', :controller => 'post', :action => 'show'
2119
- map.connect ':controller/:action/:id'
1997
+
1998
+ def test_recognize_with_conditions_and_format
1999
+ Object.const_set(:PeopleController, Class.new)
2000
+
2001
+ set.draw do |map|
2002
+ map.with_options(:controller => "people") do |people|
2003
+ people.person "/people/:id", :action => "show", :conditions => { :method => :get }
2004
+ people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
2005
+ people.connect "/people/:id.:_format", :action => "show", :conditions => { :method => :get }
2006
+ end
2007
+ end
2008
+
2009
+ request.path = "/people/5"
2010
+ request.method = :get
2011
+ assert_nothing_raised { set.recognize(request) }
2012
+ assert_equal("show", request.path_parameters[:action])
2013
+ assert_equal("5", request.path_parameters[:id])
2014
+
2015
+ request.method = :put
2016
+ assert_nothing_raised { set.recognize(request) }
2017
+ assert_equal("update", request.path_parameters[:action])
2018
+
2019
+ request.path = "/people/5.png"
2020
+ request.method = :get
2021
+ assert_nothing_raised { set.recognize(request) }
2022
+ assert_equal("show", request.path_parameters[:action])
2023
+ assert_equal("5", request.path_parameters[:id])
2024
+ assert_equal("png", request.path_parameters[:_format])
2025
+ ensure
2026
+ Object.send(:remove_const, :PeopleController)
2120
2027
  end
2121
- assert_equal '/post/edit?parameter=1', set.generate(
2122
- {:action => 'edit', :parameter => 1},
2123
- {:controller => 'post', :action => 'show', :parameter => 1}
2124
- )
2125
- end
2126
2028
 
2127
- def test_expiry_determination_should_consider_values_with_to_param
2128
- set.draw { |map| map.connect 'projects/:project_id/:controller/:action' }
2129
- assert_equal '/projects/1/post/show', set.generate(
2130
- {:action => 'show', :project_id => 1},
2131
- {:controller => 'post', :action => 'show', :project_id => '1'})
2132
- end
2029
+ def test_generate_with_default_action
2030
+ set.draw do |map|
2031
+ map.connect "/people", :controller => "people"
2032
+ map.connect "/people/list", :controller => "people", :action => "list"
2033
+ end
2133
2034
 
2134
- def test_generate_all
2135
- set.draw do |map|
2136
- map.connect 'show_post/:id', :controller => 'post', :action => 'show'
2137
- map.connect ':controller/:action/:id'
2035
+ url = set.generate(:controller => "people", :action => "list")
2036
+ assert_equal "/people/list", url
2138
2037
  end
2139
- all = set.generate(
2140
- {:action => 'show', :id => 10, :generate_all => true},
2141
- {:controller => 'post', :action => 'show'}
2142
- )
2143
- assert_equal 2, all.length
2144
- assert_equal '/show_post/10', all.first
2145
- assert_equal '/post/show/10', all.last
2146
- end
2147
-
2148
- def test_named_route_in_nested_resource
2149
- set.draw do |map|
2150
- map.resources :projects do |project|
2151
- project.milestones 'milestones', :controller => 'milestones', :action => 'index'
2152
- end
2153
- end
2154
-
2155
- request.path = "/projects/1/milestones"
2156
- request.method = :get
2157
- assert_nothing_raised { set.recognize(request) }
2158
- assert_equal("milestones", request.path_parameters[:controller])
2159
- assert_equal("index", request.path_parameters[:action])
2160
- end
2161
-
2162
- def test_setting_root_in_namespace_using_symbol
2163
- assert_nothing_raised do
2038
+
2039
+ def test_root_map
2040
+ Object.const_set(:PeopleController, Class.new)
2041
+
2042
+ set.draw { |map| map.root :controller => "people" }
2043
+
2044
+ request.path = ""
2045
+ request.method = :get
2046
+ assert_nothing_raised { set.recognize(request) }
2047
+ assert_equal("people", request.path_parameters[:controller])
2048
+ assert_equal("index", request.path_parameters[:action])
2049
+ ensure
2050
+ Object.send(:remove_const, :PeopleController)
2051
+ end
2052
+
2053
+ def test_namespace
2054
+ Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
2055
+
2164
2056
  set.draw do |map|
2165
- map.namespace :admin do |admin|
2166
- admin.root :controller => 'home'
2057
+
2058
+ map.namespace 'api' do |api|
2059
+ api.route 'inventory', :controller => "products", :action => 'inventory'
2167
2060
  end
2061
+
2168
2062
  end
2063
+
2064
+ request.path = "/api/inventory"
2065
+ request.method = :get
2066
+ assert_nothing_raised { set.recognize(request) }
2067
+ assert_equal("api/products", request.path_parameters[:controller])
2068
+ assert_equal("inventory", request.path_parameters[:action])
2069
+ ensure
2070
+ Object.send(:remove_const, :Api)
2169
2071
  end
2170
- end
2171
-
2172
- def test_setting_root_in_namespace_using_string
2173
- assert_nothing_raised do
2072
+
2073
+ def test_namespaced_root_map
2074
+ Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
2075
+
2174
2076
  set.draw do |map|
2175
- map.namespace 'admin' do |admin|
2176
- admin.root :controller => 'home'
2077
+
2078
+ map.namespace 'api' do |api|
2079
+ api.root :controller => "products"
2177
2080
  end
2081
+
2178
2082
  end
2083
+
2084
+ request.path = "/api"
2085
+ request.method = :get
2086
+ assert_nothing_raised { set.recognize(request) }
2087
+ assert_equal("api/products", request.path_parameters[:controller])
2088
+ assert_equal("index", request.path_parameters[:action])
2089
+ ensure
2090
+ Object.send(:remove_const, :Api)
2179
2091
  end
2180
- end
2181
2092
 
2182
- def test_route_requirements_with_unsupported_regexp_options_must_error
2183
- assert_raises ArgumentError do
2093
+ def test_namespace_with_path_prefix
2094
+ Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
2095
+
2184
2096
  set.draw do |map|
2185
- map.connect 'page/:name', :controller => 'pages',
2186
- :action => 'show',
2187
- :requirements => {:name => /(david|jamis)/m}
2097
+
2098
+ map.namespace 'api', :path_prefix => 'prefix' do |api|
2099
+ api.route 'inventory', :controller => "products", :action => 'inventory'
2100
+ end
2101
+
2188
2102
  end
2103
+
2104
+ request.path = "/prefix/inventory"
2105
+ request.method = :get
2106
+ assert_nothing_raised { set.recognize(request) }
2107
+ assert_equal("api/products", request.path_parameters[:controller])
2108
+ assert_equal("inventory", request.path_parameters[:action])
2109
+ ensure
2110
+ Object.send(:remove_const, :Api)
2189
2111
  end
2190
- end
2191
2112
 
2192
- def test_route_requirements_with_supported_options_must_not_error
2193
- assert_nothing_raised do
2113
+ def test_generate_finds_best_fit
2194
2114
  set.draw do |map|
2195
- map.connect 'page/:name', :controller => 'pages',
2196
- :action => 'show',
2197
- :requirements => {:name => /(david|jamis)/i}
2115
+ map.connect "/people", :controller => "people", :action => "index"
2116
+ map.connect "/ws/people", :controller => "people", :action => "index", :ws => true
2198
2117
  end
2118
+
2119
+ url = set.generate(:controller => "people", :action => "index", :ws => true)
2120
+ assert_equal "/ws/people", url
2121
+ end
2122
+
2123
+ def test_generate_changes_controller_module
2124
+ set.draw { |map| map.connect ':controller/:action/:id' }
2125
+ current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
2126
+ url = set.generate({:controller => "foo/bar", :action => "baz", :id => 7}, current)
2127
+ assert_equal "/foo/bar/baz/7", url
2199
2128
  end
2200
- assert_nothing_raised do
2129
+
2130
+ def test_id_is_not_impossibly_sticky
2201
2131
  set.draw do |map|
2202
- map.connect 'page/:name', :controller => 'pages',
2203
- :action => 'show',
2204
- :requirements => {:name => / # Desperately overcommented regexp
2205
- ( #Either
2206
- david #The Creator
2207
- | #Or
2208
- jamis #The Deployer
2209
- )/x}
2132
+ map.connect 'foo/:number', :controller => "people", :action => "index"
2133
+ map.connect ':controller/:action/:id'
2210
2134
  end
2135
+
2136
+ url = set.generate({:controller => "people", :action => "index", :number => 3},
2137
+ {:controller => "people", :action => "index", :id => "21"})
2138
+ assert_equal "/foo/3", url
2211
2139
  end
2212
- end
2213
2140
 
2214
- def test_route_requirement_recognize_with_ignore_case
2215
- set.draw do |map|
2216
- map.connect 'page/:name', :controller => 'pages',
2217
- :action => 'show',
2218
- :requirements => {:name => /(david|jamis)/i}
2141
+ def test_id_is_sticky_when_it_ought_to_be
2142
+ set.draw do |map|
2143
+ map.connect ':controller/:id/:action'
2144
+ end
2145
+
2146
+ url = set.generate({:action => "destroy"}, {:controller => "people", :action => "show", :id => "7"})
2147
+ assert_equal "/people/7/destroy", url
2219
2148
  end
2220
- assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
2221
- assert_raises ActionController::RoutingError do
2222
- set.recognize_path('/page/davidjamis')
2149
+
2150
+ def test_use_static_path_when_possible
2151
+ set.draw do |map|
2152
+ map.connect 'about', :controller => "welcome", :action => "about"
2153
+ map.connect ':controller/:action/:id'
2154
+ end
2155
+
2156
+ url = set.generate({:controller => "welcome", :action => "about"},
2157
+ {:controller => "welcome", :action => "get", :id => "7"})
2158
+ assert_equal "/about", url
2223
2159
  end
2224
- assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID'))
2225
- end
2226
2160
 
2227
- def test_route_requirement_generate_with_ignore_case
2228
- set.draw do |map|
2229
- map.connect 'page/:name', :controller => 'pages',
2230
- :action => 'show',
2231
- :requirements => {:name => /(david|jamis)/i}
2161
+ def test_generate
2162
+ set.draw { |map| map.connect ':controller/:action/:id' }
2163
+
2164
+ args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
2165
+ assert_equal "/foo/bar/7?x=y", set.generate(args)
2166
+ assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
2167
+ assert_equal [:x], set.extra_keys(args)
2232
2168
  end
2233
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
2234
- assert_equal "/page/david", url
2235
- assert_raises ActionController::RoutingError do
2236
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'})
2169
+
2170
+ def test_generate_with_path_prefix
2171
+ set.draw { |map| map.connect ':controller/:action/:id', :path_prefix => 'my' }
2172
+
2173
+ args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
2174
+ assert_equal "/my/foo/bar/7?x=y", set.generate(args)
2237
2175
  end
2238
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
2239
- assert_equal "/page/JAMIS", url
2240
- end
2241
2176
 
2242
- def test_route_requirement_recognize_with_extended_syntax
2243
- set.draw do |map|
2244
- map.connect 'page/:name', :controller => 'pages',
2245
- :action => 'show',
2246
- :requirements => {:name => / # Desperately overcommented regexp
2247
- ( #Either
2248
- david #The Creator
2249
- | #Or
2250
- jamis #The Deployer
2251
- )/x}
2177
+ def test_named_routes_are_never_relative_to_modules
2178
+ set.draw do |map|
2179
+ map.connect "/connection/manage/:action", :controller => 'connection/manage'
2180
+ map.connect "/connection/connection", :controller => "connection/connection"
2181
+ map.family_connection "/connection", :controller => "connection"
2182
+ end
2183
+
2184
+ url = set.generate({:controller => "connection"}, {:controller => 'connection/manage'})
2185
+ assert_equal "/connection/connection", url
2186
+
2187
+ url = set.generate({:use_route => :family_connection, :controller => "connection"}, {:controller => 'connection/manage'})
2188
+ assert_equal "/connection", url
2252
2189
  end
2253
- assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
2254
- assert_equal({:controller => 'pages', :action => 'show', :name => 'david'}, set.recognize_path('/page/david'))
2255
- assert_raises ActionController::RoutingError do
2256
- set.recognize_path('/page/david #The Creator')
2190
+
2191
+ def test_action_left_off_when_id_is_recalled
2192
+ set.draw do |map|
2193
+ map.connect ':controller/:action/:id'
2194
+ end
2195
+ assert_equal '/post', set.generate(
2196
+ {:controller => 'post', :action => 'index'},
2197
+ {:controller => 'post', :action => 'show', :id => '10'}
2198
+ )
2257
2199
  end
2258
- assert_raises ActionController::RoutingError do
2259
- set.recognize_path('/page/David')
2200
+
2201
+ def test_query_params_will_be_shown_when_recalled
2202
+ set.draw do |map|
2203
+ map.connect 'show_post/:parameter', :controller => 'post', :action => 'show'
2204
+ map.connect ':controller/:action/:id'
2205
+ end
2206
+ assert_equal '/post/edit?parameter=1', set.generate(
2207
+ {:action => 'edit', :parameter => 1},
2208
+ {:controller => 'post', :action => 'show', :parameter => 1}
2209
+ )
2260
2210
  end
2261
- end
2262
2211
 
2263
- def test_route_requirement_generate_with_extended_syntax
2264
- set.draw do |map|
2265
- map.connect 'page/:name', :controller => 'pages',
2266
- :action => 'show',
2267
- :requirements => {:name => / # Desperately overcommented regexp
2268
- ( #Either
2269
- david #The Creator
2270
- | #Or
2271
- jamis #The Deployer
2272
- )/x}
2212
+ def test_expiry_determination_should_consider_values_with_to_param
2213
+ set.draw { |map| map.connect 'projects/:project_id/:controller/:action' }
2214
+ assert_equal '/projects/1/post/show', set.generate(
2215
+ {:action => 'show', :project_id => 1},
2216
+ {:controller => 'post', :action => 'show', :project_id => '1'})
2273
2217
  end
2274
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
2275
- assert_equal "/page/david", url
2276
- assert_raises ActionController::RoutingError do
2277
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'})
2218
+
2219
+ def test_generate_all
2220
+ set.draw do |map|
2221
+ map.connect 'show_post/:id', :controller => 'post', :action => 'show'
2222
+ map.connect ':controller/:action/:id'
2223
+ end
2224
+ all = set.generate(
2225
+ {:action => 'show', :id => 10, :generate_all => true},
2226
+ {:controller => 'post', :action => 'show'}
2227
+ )
2228
+ assert_equal 2, all.length
2229
+ assert_equal '/show_post/10', all.first
2230
+ assert_equal '/post/show/10', all.last
2278
2231
  end
2279
- assert_raises ActionController::RoutingError do
2280
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
2232
+
2233
+ def test_named_route_in_nested_resource
2234
+ set.draw do |map|
2235
+ map.resources :projects do |project|
2236
+ project.milestones 'milestones', :controller => 'milestones', :action => 'index'
2237
+ end
2238
+ end
2239
+
2240
+ request.path = "/projects/1/milestones"
2241
+ request.method = :get
2242
+ assert_nothing_raised { set.recognize(request) }
2243
+ assert_equal("milestones", request.path_parameters[:controller])
2244
+ assert_equal("index", request.path_parameters[:action])
2281
2245
  end
2282
- end
2283
2246
 
2284
- def test_route_requirement_generate_with_xi_modifiers
2285
- set.draw do |map|
2286
- map.connect 'page/:name', :controller => 'pages',
2287
- :action => 'show',
2288
- :requirements => {:name => / # Desperately overcommented regexp
2289
- ( #Either
2290
- david #The Creator
2291
- | #Or
2292
- jamis #The Deployer
2293
- )/xi}
2247
+ def test_setting_root_in_namespace_using_symbol
2248
+ assert_nothing_raised do
2249
+ set.draw do |map|
2250
+ map.namespace :admin do |admin|
2251
+ admin.root :controller => 'home'
2252
+ end
2253
+ end
2254
+ end
2294
2255
  end
2295
- url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
2296
- assert_equal "/page/JAMIS", url
2297
- end
2298
2256
 
2299
- def test_route_requirement_recognize_with_xi_modifiers
2300
- set.draw do |map|
2301
- map.connect 'page/:name', :controller => 'pages',
2302
- :action => 'show',
2303
- :requirements => {:name => / # Desperately overcommented regexp
2304
- ( #Either
2305
- david #The Creator
2306
- | #Or
2307
- jamis #The Deployer
2308
- )/xi}
2257
+ def test_setting_root_in_namespace_using_string
2258
+ assert_nothing_raised do
2259
+ set.draw do |map|
2260
+ map.namespace 'admin' do |admin|
2261
+ admin.root :controller => 'home'
2262
+ end
2263
+ end
2264
+ end
2309
2265
  end
2310
- assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'}, set.recognize_path('/page/JAMIS'))
2311
- end
2312
2266
 
2313
-
2314
- end
2267
+ def test_route_requirements_with_unsupported_regexp_options_must_error
2268
+ assert_raises ArgumentError do
2269
+ set.draw do |map|
2270
+ map.connect 'page/:name', :controller => 'pages',
2271
+ :action => 'show',
2272
+ :requirements => {:name => /(david|jamis)/m}
2273
+ end
2274
+ end
2275
+ end
2315
2276
 
2316
- class RoutingTest < Test::Unit::TestCase
2317
-
2318
- def test_possible_controllers
2319
- true_controller_paths = ActionController::Routing.controller_paths
2277
+ def test_route_requirements_with_supported_options_must_not_error
2278
+ assert_nothing_raised do
2279
+ set.draw do |map|
2280
+ map.connect 'page/:name', :controller => 'pages',
2281
+ :action => 'show',
2282
+ :requirements => {:name => /(david|jamis)/i}
2283
+ end
2284
+ end
2285
+ assert_nothing_raised do
2286
+ set.draw do |map|
2287
+ map.connect 'page/:name', :controller => 'pages',
2288
+ :action => 'show',
2289
+ :requirements => {:name => / # Desperately overcommented regexp
2290
+ ( #Either
2291
+ david #The Creator
2292
+ | #Or
2293
+ jamis #The Deployer
2294
+ )/x}
2295
+ end
2296
+ end
2297
+ end
2320
2298
 
2321
- ActionController::Routing.use_controllers! nil
2299
+ def test_route_requirement_recognize_with_ignore_case
2300
+ set.draw do |map|
2301
+ map.connect 'page/:name', :controller => 'pages',
2302
+ :action => 'show',
2303
+ :requirements => {:name => /(david|jamis)/i}
2304
+ end
2305
+ assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
2306
+ assert_raises ActionController::RoutingError do
2307
+ set.recognize_path('/page/davidjamis')
2308
+ end
2309
+ assert_equal({:controller => 'pages', :action => 'show', :name => 'DAVID'}, set.recognize_path('/page/DAVID'))
2310
+ end
2322
2311
 
2323
- silence_warnings do
2324
- Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
2312
+ def test_route_requirement_generate_with_ignore_case
2313
+ set.draw do |map|
2314
+ map.connect 'page/:name', :controller => 'pages',
2315
+ :action => 'show',
2316
+ :requirements => {:name => /(david|jamis)/i}
2317
+ end
2318
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
2319
+ assert_equal "/page/david", url
2320
+ assert_raises ActionController::RoutingError do
2321
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'})
2322
+ end
2323
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
2324
+ assert_equal "/page/JAMIS", url
2325
2325
  end
2326
2326
 
2327
- ActionController::Routing.controller_paths = [
2328
- RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib'
2329
- ]
2330
-
2331
- assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
2332
- ensure
2333
- if true_controller_paths
2334
- ActionController::Routing.controller_paths = true_controller_paths
2327
+ def test_route_requirement_recognize_with_extended_syntax
2328
+ set.draw do |map|
2329
+ map.connect 'page/:name', :controller => 'pages',
2330
+ :action => 'show',
2331
+ :requirements => {:name => / # Desperately overcommented regexp
2332
+ ( #Either
2333
+ david #The Creator
2334
+ | #Or
2335
+ jamis #The Deployer
2336
+ )/x}
2337
+ end
2338
+ assert_equal({:controller => 'pages', :action => 'show', :name => 'jamis'}, set.recognize_path('/page/jamis'))
2339
+ assert_equal({:controller => 'pages', :action => 'show', :name => 'david'}, set.recognize_path('/page/david'))
2340
+ assert_raises ActionController::RoutingError do
2341
+ set.recognize_path('/page/david #The Creator')
2342
+ end
2343
+ assert_raises ActionController::RoutingError do
2344
+ set.recognize_path('/page/David')
2345
+ end
2335
2346
  end
2336
- ActionController::Routing.use_controllers! nil
2337
- Object.send(:remove_const, :RAILS_ROOT) rescue nil
2338
- end
2339
-
2340
- def test_possible_controllers_are_reset_on_each_load
2341
- true_possible_controllers = ActionController::Routing.possible_controllers
2342
- true_controller_paths = ActionController::Routing.controller_paths
2343
-
2344
- ActionController::Routing.use_controllers! nil
2345
- root = File.dirname(__FILE__) + '/controller_fixtures'
2346
-
2347
- ActionController::Routing.controller_paths = []
2348
- assert_equal [], ActionController::Routing.possible_controllers
2349
-
2350
- ActionController::Routing::Routes.load!
2351
- ActionController::Routing.controller_paths = [
2352
- root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib'
2353
- ]
2354
-
2355
- assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
2356
- ensure
2357
- ActionController::Routing.controller_paths = true_controller_paths
2358
- ActionController::Routing.use_controllers! true_possible_controllers
2359
- Object.send(:remove_const, :RAILS_ROOT) rescue nil
2360
-
2361
- ActionController::Routing::Routes.clear!
2362
- ActionController::Routing::Routes.load_routes!
2363
- end
2364
-
2365
- def test_with_controllers
2366
- c = %w(admin/accounts admin/users account pages)
2367
- ActionController::Routing.with_controllers c do
2368
- assert_equal c, ActionController::Routing.possible_controllers
2347
+
2348
+ def test_route_requirement_generate_with_extended_syntax
2349
+ set.draw do |map|
2350
+ map.connect 'page/:name', :controller => 'pages',
2351
+ :action => 'show',
2352
+ :requirements => {:name => / # Desperately overcommented regexp
2353
+ ( #Either
2354
+ david #The Creator
2355
+ | #Or
2356
+ jamis #The Deployer
2357
+ )/x}
2358
+ end
2359
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'david'})
2360
+ assert_equal "/page/david", url
2361
+ assert_raises ActionController::RoutingError do
2362
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'davidjamis'})
2363
+ end
2364
+ assert_raises ActionController::RoutingError do
2365
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
2366
+ end
2369
2367
  end
2370
- end
2371
2368
 
2372
- def test_normalize_unix_paths
2373
- load_paths = %w(. config/../app/controllers config/../app//helpers script/../config/../vendor/rails/actionpack/lib vendor/rails/railties/builtin/rails_info app/models lib script/../config/../foo/bar/../../app/models .foo/../.bar foo.bar/../config)
2374
- paths = ActionController::Routing.normalize_paths(load_paths)
2375
- assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models config .bar lib .), paths
2376
- end
2369
+ def test_route_requirement_generate_with_xi_modifiers
2370
+ set.draw do |map|
2371
+ map.connect 'page/:name', :controller => 'pages',
2372
+ :action => 'show',
2373
+ :requirements => {:name => / # Desperately overcommented regexp
2374
+ ( #Either
2375
+ david #The Creator
2376
+ | #Or
2377
+ jamis #The Deployer
2378
+ )/xi}
2379
+ end
2380
+ url = set.generate({:controller => 'pages', :action => 'show', :name => 'JAMIS'})
2381
+ assert_equal "/page/JAMIS", url
2382
+ end
2377
2383
 
2378
- def test_normalize_windows_paths
2379
- load_paths = %w(. config\\..\\app\\controllers config\\..\\app\\\\helpers script\\..\\config\\..\\vendor\\rails\\actionpack\\lib vendor\\rails\\railties\\builtin\\rails_info app\\models lib script\\..\\config\\..\\foo\\bar\\..\\..\\app\\models .foo\\..\\.bar foo.bar\\..\\config)
2380
- paths = ActionController::Routing.normalize_paths(load_paths)
2381
- assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models config .bar lib .), paths
2382
- end
2383
-
2384
- def test_routing_helper_module
2385
- assert_kind_of Module, ActionController::Routing::Helpers
2386
-
2387
- h = ActionController::Routing::Helpers
2388
- c = Class.new
2389
- assert ! c.ancestors.include?(h)
2390
- ActionController::Routing::Routes.install_helpers c
2391
- assert c.ancestors.include?(h)
2384
+ def test_route_requirement_recognize_with_xi_modifiers
2385
+ set.draw do |map|
2386
+ map.connect 'page/:name', :controller => 'pages',
2387
+ :action => 'show',
2388
+ :requirements => {:name => / # Desperately overcommented regexp
2389
+ ( #Either
2390
+ david #The Creator
2391
+ | #Or
2392
+ jamis #The Deployer
2393
+ )/xi}
2394
+ end
2395
+ assert_equal({:controller => 'pages', :action => 'show', :name => 'JAMIS'}, set.recognize_path('/page/JAMIS'))
2396
+ end
2392
2397
  end
2393
2398
 
2394
- end
2395
-
2396
- uses_mocha 'route loading' do
2397
2399
  class RouteLoadingTest < Test::Unit::TestCase
2398
-
2399
2400
  def setup
2400
2401
  routes.instance_variable_set '@routes_last_modified', nil
2401
2402
  silence_warnings { Object.const_set :RAILS_ROOT, '.' }
@@ -2446,7 +2447,7 @@ uses_mocha 'route loading' do
2446
2447
 
2447
2448
  ActiveSupport::Inflector.inflections { |inflect| inflect.uncountable('equipment') }
2448
2449
  end
2449
-
2450
+
2450
2451
  def test_load_with_configuration
2451
2452
  routes.configuration_file = "foobarbaz"
2452
2453
  File.expects(:stat).returns(@stat)
@@ -2456,9 +2457,8 @@ uses_mocha 'route loading' do
2456
2457
  end
2457
2458
 
2458
2459
  private
2459
- def routes
2460
- ActionController::Routing::Routes
2461
- end
2462
-
2460
+ def routes
2461
+ ActionController::Routing::Routes
2462
+ end
2463
2463
  end
2464
2464
  end