actionpack 1.12.5 → 1.13.0

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 (179) hide show
  1. data/CHANGELOG +517 -15
  2. data/MIT-LICENSE +1 -1
  3. data/README +18 -20
  4. data/Rakefile +7 -4
  5. data/examples/address_book_controller.rb +3 -3
  6. data/examples/blog_controller.cgi +3 -3
  7. data/examples/debate_controller.cgi +5 -5
  8. data/lib/action_controller.rb +2 -2
  9. data/lib/action_controller/assertions.rb +73 -311
  10. data/lib/action_controller/{deprecated_assertions.rb → assertions/deprecated_assertions.rb} +32 -8
  11. data/lib/action_controller/assertions/dom_assertions.rb +25 -0
  12. data/lib/action_controller/assertions/model_assertions.rb +12 -0
  13. data/lib/action_controller/assertions/response_assertions.rb +140 -0
  14. data/lib/action_controller/assertions/routing_assertions.rb +82 -0
  15. data/lib/action_controller/assertions/selector_assertions.rb +571 -0
  16. data/lib/action_controller/assertions/tag_assertions.rb +117 -0
  17. data/lib/action_controller/base.rb +334 -163
  18. data/lib/action_controller/benchmarking.rb +3 -6
  19. data/lib/action_controller/caching.rb +83 -22
  20. data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -7
  21. data/lib/action_controller/cgi_ext/cgi_methods.rb +167 -173
  22. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +43 -22
  23. data/lib/action_controller/cgi_process.rb +50 -27
  24. data/lib/action_controller/components.rb +21 -25
  25. data/lib/action_controller/cookies.rb +10 -9
  26. data/lib/action_controller/{dependencies.rb → deprecated_dependencies.rb} +9 -27
  27. data/lib/action_controller/filters.rb +448 -225
  28. data/lib/action_controller/flash.rb +24 -20
  29. data/lib/action_controller/helpers.rb +2 -5
  30. data/lib/action_controller/integration.rb +40 -16
  31. data/lib/action_controller/layout.rb +11 -8
  32. data/lib/action_controller/macros/auto_complete.rb +3 -2
  33. data/lib/action_controller/macros/in_place_editing.rb +3 -2
  34. data/lib/action_controller/mime_responds.rb +41 -29
  35. data/lib/action_controller/mime_type.rb +68 -10
  36. data/lib/action_controller/pagination.rb +4 -3
  37. data/lib/action_controller/request.rb +22 -14
  38. data/lib/action_controller/rescue.rb +25 -22
  39. data/lib/action_controller/resources.rb +302 -0
  40. data/lib/action_controller/response.rb +20 -2
  41. data/lib/action_controller/response.rb.rej +17 -0
  42. data/lib/action_controller/routing.rb +1165 -567
  43. data/lib/action_controller/scaffolding.rb +30 -31
  44. data/lib/action_controller/session/active_record_store.rb +2 -0
  45. data/lib/action_controller/session/drb_store.rb +4 -0
  46. data/lib/action_controller/session/mem_cache_store.rb +4 -0
  47. data/lib/action_controller/session_management.rb +6 -9
  48. data/lib/action_controller/status_codes.rb +89 -0
  49. data/lib/action_controller/streaming.rb +6 -15
  50. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +5 -5
  51. data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -2
  52. data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -4
  53. data/lib/action_controller/templates/rescues/template_error.rhtml +1 -1
  54. data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
  55. data/lib/action_controller/test_process.rb +52 -30
  56. data/lib/action_controller/url_rewriter.rb +63 -29
  57. data/lib/action_controller/vendor/html-scanner/html/document.rb +1 -0
  58. data/lib/action_controller/vendor/html-scanner/html/node.rb +3 -4
  59. data/lib/action_controller/vendor/html-scanner/html/selector.rb +822 -0
  60. data/lib/action_controller/verification.rb +22 -11
  61. data/lib/action_pack.rb +1 -1
  62. data/lib/action_pack/version.rb +2 -2
  63. data/lib/action_view.rb +1 -1
  64. data/lib/action_view/base.rb +46 -43
  65. data/lib/action_view/compiled_templates.rb +1 -1
  66. data/lib/action_view/helpers/active_record_helper.rb +54 -17
  67. data/lib/action_view/helpers/asset_tag_helper.rb +97 -46
  68. data/lib/action_view/helpers/capture_helper.rb +1 -1
  69. data/lib/action_view/helpers/date_helper.rb +258 -136
  70. data/lib/action_view/helpers/debug_helper.rb +1 -1
  71. data/lib/action_view/helpers/deprecated_helper.rb +34 -0
  72. data/lib/action_view/helpers/form_helper.rb +75 -35
  73. data/lib/action_view/helpers/form_options_helper.rb +7 -5
  74. data/lib/action_view/helpers/form_tag_helper.rb +44 -6
  75. data/lib/action_view/helpers/java_script_macros_helper.rb +59 -46
  76. data/lib/action_view/helpers/javascript_helper.rb +71 -10
  77. data/lib/action_view/helpers/javascripts/controls.js +41 -23
  78. data/lib/action_view/helpers/javascripts/dragdrop.js +105 -76
  79. data/lib/action_view/helpers/javascripts/effects.js +293 -163
  80. data/lib/action_view/helpers/javascripts/prototype.js +897 -389
  81. data/lib/action_view/helpers/javascripts/prototype.js.rej +561 -0
  82. data/lib/action_view/helpers/number_helper.rb +111 -65
  83. data/lib/action_view/helpers/prototype_helper.rb +84 -109
  84. data/lib/action_view/helpers/scriptaculous_helper.rb +5 -0
  85. data/lib/action_view/helpers/tag_helper.rb +69 -16
  86. data/lib/action_view/helpers/text_helper.rb +149 -112
  87. data/lib/action_view/helpers/url_helper.rb +200 -107
  88. data/lib/action_view/template_error.rb +66 -42
  89. data/test/abstract_unit.rb +4 -2
  90. data/test/active_record_unit.rb +84 -56
  91. data/test/activerecord/active_record_assertions_test.rb +26 -18
  92. data/test/activerecord/active_record_store_test.rb +4 -36
  93. data/test/activerecord/pagination_test.rb +1 -6
  94. data/test/controller/action_pack_assertions_test.rb +230 -113
  95. data/test/controller/addresses_render_test.rb +2 -6
  96. data/test/controller/assert_select_test.rb +576 -0
  97. data/test/controller/base_test.rb +73 -3
  98. data/test/controller/caching_test.rb +228 -0
  99. data/test/controller/capture_test.rb +12 -10
  100. data/test/controller/cgi_test.rb +89 -12
  101. data/test/controller/components_test.rb +24 -2
  102. data/test/controller/content_type_test.rb +139 -0
  103. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  104. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  105. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  106. data/test/controller/cookie_test.rb +33 -25
  107. data/test/controller/deprecated_instance_variables_test.rb +48 -0
  108. data/test/controller/deprecation/deprecated_base_methods_test.rb +60 -0
  109. data/test/controller/fake_controllers.rb +0 -1
  110. data/test/controller/filters_test.rb +301 -16
  111. data/test/controller/flash_test.rb +19 -2
  112. data/test/controller/helper_test.rb +2 -2
  113. data/test/controller/integration_test.rb +154 -0
  114. data/test/controller/layout_test.rb +115 -1
  115. data/test/controller/mime_responds_test.rb +94 -0
  116. data/test/controller/mime_type_test.rb +9 -0
  117. data/test/controller/new_render_test.rb +161 -11
  118. data/test/controller/raw_post_test.rb +52 -15
  119. data/test/controller/redirect_test.rb +27 -14
  120. data/test/controller/render_test.rb +76 -29
  121. data/test/controller/request_test.rb +55 -4
  122. data/test/controller/resources_test.rb +274 -0
  123. data/test/controller/routing_test.rb +1533 -824
  124. data/test/controller/selector_test.rb +628 -0
  125. data/test/controller/send_file_test.rb +9 -1
  126. data/test/controller/session_management_test.rb +51 -0
  127. data/test/controller/test_test.rb +113 -29
  128. data/test/controller/url_rewriter_test.rb +86 -17
  129. data/test/controller/verification_test.rb +19 -17
  130. data/test/controller/webservice_test.rb +0 -7
  131. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  132. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  133. data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
  134. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  135. data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +1 -0
  136. data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +1 -0
  137. data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +1 -0
  138. data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +1 -0
  139. data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +1 -0
  140. data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +1 -0
  141. data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +1 -0
  142. data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +1 -0
  143. data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +1 -0
  144. data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +1 -0
  145. data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +1 -0
  146. data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +1 -0
  147. data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +1 -0
  148. data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +1 -0
  149. data/test/fixtures/multipart/binary_file +0 -0
  150. data/test/fixtures/public/javascripts/application.js +1 -0
  151. data/test/fixtures/test/_hello.rxml +1 -0
  152. data/test/fixtures/test/hello_world_container.rxml +3 -0
  153. data/test/fixtures/topic.rb +2 -2
  154. data/test/template/active_record_helper_test.rb +83 -12
  155. data/test/template/asset_tag_helper_test.rb +75 -95
  156. data/test/template/compiled_templates_test.rb +1 -0
  157. data/test/template/date_helper_test.rb +873 -181
  158. data/test/template/deprecated_helper_test.rb +36 -0
  159. data/test/template/deprecated_instance_variables_test.rb +43 -0
  160. data/test/template/form_helper_test.rb +77 -1
  161. data/test/template/form_options_helper_test.rb +4 -0
  162. data/test/template/form_tag_helper_test.rb +66 -2
  163. data/test/template/java_script_macros_helper_test.rb +4 -1
  164. data/test/template/javascript_helper_test.rb +29 -0
  165. data/test/template/number_helper_test.rb +63 -27
  166. data/test/template/prototype_helper_test.rb +77 -34
  167. data/test/template/tag_helper_test.rb +34 -6
  168. data/test/template/text_helper_test.rb +69 -34
  169. data/test/template/url_helper_test.rb +168 -16
  170. data/test/testing_sandbox.rb +7 -22
  171. metadata +66 -20
  172. data/filler.txt +0 -50
  173. data/lib/action_controller/code_generation.rb +0 -235
  174. data/lib/action_controller/vendor/xml_simple.rb +0 -1019
  175. data/test/controller/caching_filestore.rb +0 -74
  176. data/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb +0 -7
  177. data/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb +0 -3
  178. data/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb +0 -7
  179. data/test/fixtures/dont_load.rb +0 -3
@@ -1,646 +1,41 @@
1
1
  require File.dirname(__FILE__) + '/../abstract_unit'
2
2
  require 'test/unit'
3
3
  require File.dirname(__FILE__) + '/fake_controllers'
4
- require 'stringio'
4
+ require 'action_controller/routing'
5
5
 
6
6
  RunTimeTests = ARGV.include? 'time'
7
+ ROUTING = ActionController::Routing
7
8
 
8
- module ActionController::CodeGeneration
9
+ class ROUTING::RouteBuilder
10
+ attr_reader :warn_output
9
11
 
10
- class SourceTests < Test::Unit::TestCase
11
- attr_accessor :source
12
- def setup
13
- @source = Source.new
14
- end
15
-
16
- def test_initial_state
17
- assert_equal [], source.lines
18
- assert_equal 0, source.indentation_level
19
- end
20
-
21
- def test_trivial_operations
22
- source << "puts 'Hello World'"
23
- assert_equal ["puts 'Hello World'"], source.lines
24
- assert_equal "puts 'Hello World'", source.to_s
25
-
26
- source.line "puts 'Goodbye World'"
27
- assert_equal ["puts 'Hello World'", "puts 'Goodbye World'"], source.lines
28
- assert_equal "puts 'Hello World'\nputs 'Goodbye World'", source.to_s
29
- end
30
-
31
- def test_indentation
32
- source << "x = gets.to_i"
33
- source << 'if x.odd?'
34
- source.indent { source << "puts 'x is odd!'" }
35
- source << 'else'
36
- source.indent { source << "puts 'x is even!'" }
37
- source << 'end'
38
-
39
- assert_equal ["x = gets.to_i", "if x.odd?", " puts 'x is odd!'", 'else', " puts 'x is even!'", 'end'], source.lines
40
-
41
- text = "x = gets.to_i
42
- if x.odd?
43
- puts 'x is odd!'
44
- else
45
- puts 'x is even!'
46
- end"
47
-
48
- assert_equal text, source.to_s
49
- end
50
- end
51
-
52
- class CodeGeneratorTests < Test::Unit::TestCase
53
- attr_accessor :generator
54
- def setup
55
- @generator = CodeGenerator.new
56
- end
57
-
58
- def test_initial_state
59
- assert_equal [], generator.source.lines
60
- assert_equal [], generator.locals
61
- end
62
-
63
- def test_trivial_operations
64
- ["puts 'Hello World'", "puts 'Goodbye World'"].each {|l| generator << l}
65
- assert_equal ["puts 'Hello World'", "puts 'Goodbye World'"], generator.source.lines
66
- assert_equal "puts 'Hello World'\nputs 'Goodbye World'", generator.to_s
67
- end
68
-
69
- def test_if
70
- generator << "x = gets.to_i"
71
- generator.if("x.odd?") { generator << "puts 'x is odd!'" }
72
-
73
- assert_equal "x = gets.to_i\nif x.odd?\n puts 'x is odd!'\nend", generator.to_s
74
- end
75
-
76
- def test_else
77
- test_if
78
- generator.else { generator << "puts 'x is even!'" }
79
-
80
- assert_equal "x = gets.to_i\nif x.odd?\n puts 'x is odd!'\nelse \n puts 'x is even!'\nend", generator.to_s
81
- end
82
-
83
- def test_dup
84
- generator << 'x = 2'
85
- generator.locals << :x
86
-
87
- g = generator.dup
88
- assert_equal generator.source, g.source
89
- assert_equal generator.locals, g.locals
90
-
91
- g << 'y = 3'
92
- g.locals << :y
93
- assert_equal [:x, :y], g.locals # Make sure they don't share the same array.
94
- assert_equal [:x], generator.locals
95
- end
96
- end
97
-
98
- class RecognitionTests < Test::Unit::TestCase
99
- attr_accessor :generator
100
- alias :g :generator
101
- def setup
102
- @generator = RecognitionGenerator.new
103
- end
104
-
105
- def go(components)
106
- g.current = components.first
107
- g.after = components[1..-1] || []
108
- g.go
109
- end
110
-
111
- def execute(path, show = false)
112
- path = path.split('/') if path.is_a? String
113
- source = "index, path = 0, #{path.inspect}\n#{g.to_s}"
114
- puts source if show
115
- r = eval source
116
- r ? r.symbolize_keys : nil
117
- end
118
-
119
- Static = ::ActionController::Routing::StaticComponent
120
- Dynamic = ::ActionController::Routing::DynamicComponent
121
- Path = ::ActionController::Routing::PathComponent
122
- Controller = ::ActionController::Routing::ControllerComponent
123
-
124
- def test_all_static
125
- c = %w(hello world how are you).collect {|str| Static.new(str)}
126
-
127
- g.result :controller, "::ContentController", true
128
- g.constant_result :action, 'index'
129
-
130
- go c
131
-
132
- assert_nil execute('x')
133
- assert_nil execute('hello/world/how')
134
- assert_nil execute('hello/world/how/are')
135
- assert_nil execute('hello/world/how/are/you/today')
136
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hello/world/how/are/you'))
137
- end
138
-
139
- def test_basic_dynamic
140
- c = [Static.new("hi"), Dynamic.new(:action)]
141
- g.result :controller, "::ContentController", true
142
- go c
143
-
144
- assert_nil execute('boo')
145
- assert_nil execute('boo/blah')
146
- assert_nil execute('hi')
147
- assert_nil execute('hi/dude/what')
148
- assert_equal({:controller => ::ContentController, :action => 'dude'}, execute('hi/dude'))
149
- end
150
-
151
- def test_basic_dynamic_backwards
152
- c = [Dynamic.new(:action), Static.new("hi")]
153
- go c
154
-
155
- assert_nil execute('')
156
- assert_nil execute('boo')
157
- assert_nil execute('boo/blah')
158
- assert_nil execute('hi')
159
- assert_equal({:action => 'index'}, execute('index/hi'))
160
- assert_equal({:action => 'show'}, execute('show/hi'))
161
- assert_nil execute('hi/dude')
162
- end
163
-
164
- def test_dynamic_with_default
165
- c = [Static.new("hi"), Dynamic.new(:action, :default => 'index')]
166
- g.result :controller, "::ContentController", true
167
- go c
168
-
169
- assert_nil execute('boo')
170
- assert_nil execute('boo/blah')
171
- assert_nil execute('hi/dude/what')
172
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hi'))
173
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hi/index'))
174
- assert_equal({:controller => ::ContentController, :action => 'dude'}, execute('hi/dude'))
175
- end
176
-
177
- def test_dynamic_with_string_condition
178
- c = [Static.new("hi"), Dynamic.new(:action, :condition => 'index')]
179
- g.result :controller, "::ContentController", true
180
- go c
181
-
182
- assert_nil execute('boo')
183
- assert_nil execute('boo/blah')
184
- assert_nil execute('hi')
185
- assert_nil execute('hi/dude/what')
186
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hi/index'))
187
- assert_nil execute('hi/dude')
188
- end
189
-
190
- def test_dynamic_with_string_condition_backwards
191
- c = [Dynamic.new(:action, :condition => 'index'), Static.new("hi")]
192
- g.result :controller, "::ContentController", true
193
- go c
194
-
195
- assert_nil execute('boo')
196
- assert_nil execute('boo/blah')
197
- assert_nil execute('hi')
198
- assert_nil execute('dude/what/hi')
199
- assert_nil execute('index/what')
200
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('index/hi'))
201
- assert_nil execute('dude/hi')
202
- end
203
-
204
- def test_dynamic_with_regexp_condition
205
- c = [Static.new("hi"), Dynamic.new(:action, :condition => /^[a-z]+$/)]
206
- g.result :controller, "::ContentController", true
207
- go c
208
-
209
- assert_nil execute('boo')
210
- assert_nil execute('boo/blah')
211
- assert_nil execute('hi')
212
- assert_nil execute('hi/FOXY')
213
- assert_nil execute('hi/138708jkhdf')
214
- assert_nil execute('hi/dkjfl8792343dfsf')
215
- assert_nil execute('hi/dude/what')
216
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hi/index'))
217
- assert_equal({:controller => ::ContentController, :action => 'dude'}, execute('hi/dude'))
218
- end
219
-
220
- def test_dynamic_with_regexp_and_default
221
- c = [Static.new("hi"), Dynamic.new(:action, :condition => /^[a-z]+$/, :default => 'index')]
222
- g.result :controller, "::ContentController", true
223
- go c
224
-
225
- assert_nil execute('boo')
226
- assert_nil execute('boo/blah')
227
- assert_nil execute('hi/FOXY')
228
- assert_nil execute('hi/138708jkhdf')
229
- assert_nil execute('hi/dkjfl8792343dfsf')
230
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hi'))
231
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('hi/index'))
232
- assert_equal({:controller => ::ContentController, :action => 'dude'}, execute('hi/dude'))
233
- assert_nil execute('hi/dude/what')
234
- end
235
-
236
- def test_path
237
- c = [Static.new("hi"), Path.new(:file)]
238
- g.result :controller, "::ContentController", true
239
- g.constant_result :action, "download"
240
-
241
- go c
242
-
243
- assert_nil execute('boo')
244
- assert_nil execute('boo/blah')
245
- assert_equal({:controller => ::ContentController, :action => 'download', :file => []}, execute('hi'))
246
- assert_equal({:controller => ::ContentController, :action => 'download', :file => %w(books agile_rails_dev.pdf)},
247
- execute('hi/books/agile_rails_dev.pdf'))
248
- assert_equal({:controller => ::ContentController, :action => 'download', :file => ['dude']}, execute('hi/dude'))
249
- assert_equal 'dude/what', execute('hi/dude/what')[:file].to_s
250
- end
251
-
252
- def test_path_with_dynamic
253
- c = [Dynamic.new(:action), Path.new(:file)]
254
- g.result :controller, "::ContentController", true
255
-
256
- go c
257
-
258
- assert_nil execute('')
259
- assert_equal({:controller => ::ContentController, :action => 'download', :file => []}, execute('download'))
260
- assert_equal({:controller => ::ContentController, :action => 'download', :file => %w(books agile_rails_dev.pdf)},
261
- execute('download/books/agile_rails_dev.pdf'))
262
- assert_equal({:controller => ::ContentController, :action => 'download', :file => ['dude']}, execute('download/dude'))
263
- assert_equal 'dude/what', execute('hi/dude/what')[:file].to_s
264
- end
265
-
266
- def test_path_with_dynamic_and_default
267
- c = [Dynamic.new(:action, :default => 'index'), Path.new(:file)]
268
-
269
- go c
270
-
271
- assert_equal({:action => 'index', :file => []}, execute(''))
272
- assert_equal({:action => 'index', :file => []}, execute('index'))
273
- assert_equal({:action => 'blarg', :file => []}, execute('blarg'))
274
- assert_equal({:action => 'index', :file => ['content']}, execute('index/content'))
275
- assert_equal({:action => 'show', :file => ['rails_dev.pdf']}, execute('show/rails_dev.pdf'))
276
- end
277
-
278
- def test_controller
279
- c = [Static.new("hi"), Controller.new(:controller)]
280
- g.constant_result :action, "hi"
281
-
282
- go c
283
-
284
- assert_nil execute('boo')
285
- assert_nil execute('boo/blah')
286
- assert_nil execute('hi/x')
287
- assert_nil execute('hi/13870948')
288
- assert_nil execute('hi/content/dog')
289
- assert_nil execute('hi/admin/user/foo')
290
- assert_equal({:controller => ::ContentController, :action => 'hi'}, execute('hi/content'))
291
- assert_equal({:controller => ::Admin::UserController, :action => 'hi'}, execute('hi/admin/user'))
292
- end
293
-
294
- def test_controller_with_regexp
295
- c = [Static.new("hi"), Controller.new(:controller, :condition => /^admin\/.+$/)]
296
- g.constant_result :action, "hi"
297
-
298
- go c
299
-
300
- assert_nil execute('hi')
301
- assert_nil execute('hi/x')
302
- assert_nil execute('hi/content')
303
- assert_equal({:controller => ::Admin::UserController, :action => 'hi'}, execute('hi/admin/user'))
304
- assert_equal({:controller => ::Admin::NewsFeedController, :action => 'hi'}, execute('hi/admin/news_feed'))
305
- assert_nil execute('hi/admin/user/foo')
306
- end
307
-
308
- def test_standard_route(time = ::RunTimeTests)
309
- c = [Controller.new(:controller), Dynamic.new(:action, :default => 'index'), Dynamic.new(:id, :default => nil)]
310
- go c
311
-
312
- # Make sure we get the right answers
313
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute('content'))
314
- assert_equal({:controller => ::ContentController, :action => 'list'}, execute('content/list'))
315
- assert_equal({:controller => ::ContentController, :action => 'show', :id => '10'}, execute('content/show/10'))
316
-
317
- assert_equal({:controller => ::Admin::UserController, :action => 'index'}, execute('admin/user'))
318
- assert_equal({:controller => ::Admin::UserController, :action => 'list'}, execute('admin/user/list'))
319
- assert_equal({:controller => ::Admin::UserController, :action => 'show', :id => 'nseckar'}, execute('admin/user/show/nseckar'))
320
-
321
- assert_nil execute('content/show/10/20')
322
- assert_nil execute('food')
323
-
324
- if time
325
- source = "def self.execute(path)
326
- path = path.split('/') if path.is_a? String
327
- index = 0
328
- r = #{g.to_s}
329
- end"
330
- eval(source)
331
-
332
- GC.start
333
- n = 1000
334
- time = Benchmark.realtime do n.times {
335
- execute('content')
336
- execute('content/list')
337
- execute('content/show/10')
338
-
339
- execute('admin/user')
340
- execute('admin/user/list')
341
- execute('admin/user/show/nseckar')
342
-
343
- execute('admin/user/show/nseckar/dude')
344
- execute('admin/why/show/nseckar')
345
- execute('content/show/10/20')
346
- execute('food')
347
- } end
348
- time -= Benchmark.realtime do n.times { } end
349
-
350
-
351
- puts "\n\nRecognition:"
352
- per_url = time / (n * 10)
353
-
354
- puts "#{per_url * 1000} ms/url"
355
- puts "#{1 / per_url} urls/s\n\n"
356
- end
357
- end
358
-
359
- def test_default_route
360
- g.result :controller, "::ContentController", true
361
- g.constant_result :action, 'index'
362
-
363
- go []
364
-
365
- assert_nil execute('x')
366
- assert_nil execute('hello/world/how')
367
- assert_nil execute('hello/world/how/are')
368
- assert_nil execute('hello/world/how/are/you/today')
369
- assert_equal({:controller => ::ContentController, :action => 'index'}, execute([]))
370
- end
371
- end
372
-
373
- class GenerationTests < Test::Unit::TestCase
374
- attr_accessor :generator
375
- alias :g :generator
376
- def setup
377
- @generator = GenerationGenerator.new # ha!
378
- end
379
-
380
- def go(components)
381
- g.current = components.first
382
- g.after = components[1..-1] || []
383
- g.go
384
- end
385
-
386
- def execute(options, recall, show = false)
387
- source = "\n
388
- expire_on = ::ActionController::Routing.expiry_hash(options, recall)
389
- hash = merged = recall.merge(options)
390
- not_expired = true
391
-
392
- #{g.to_s}\n\n"
393
- puts source if show
394
- eval(source)
395
- end
396
-
397
- Static = ::ActionController::Routing::StaticComponent
398
- Dynamic = ::ActionController::Routing::DynamicComponent
399
- Path = ::ActionController::Routing::PathComponent
400
- Controller = ::ActionController::Routing::ControllerComponent
401
-
402
- def test_all_static_no_requirements
403
- c = [Static.new("hello"), Static.new("world")]
404
- go c
405
-
406
- assert_equal "/hello/world", execute({}, {})
407
- end
408
-
409
- def test_basic_dynamic
410
- c = [Static.new("hi"), Dynamic.new(:action)]
411
- go c
412
-
413
- assert_equal '/hi/index', execute({:action => 'index'}, {:action => 'index'})
414
- assert_equal '/hi/show', execute({:action => 'show'}, {:action => 'index'})
415
- assert_equal '/hi/list+people', execute({}, {:action => 'list people'})
416
- assert_nil execute({},{})
417
- end
418
-
419
- def test_dynamic_with_default
420
- c = [Static.new("hi"), Dynamic.new(:action, :default => 'index')]
421
- go c
422
-
423
- assert_equal '/hi', execute({:action => 'index'}, {:action => 'index'})
424
- assert_equal '/hi/show', execute({:action => 'show'}, {:action => 'index'})
425
- assert_equal '/hi/list+people', execute({}, {:action => 'list people'})
426
- assert_equal '/hi', execute({}, {})
427
- end
428
-
429
- def test_dynamic_with_regexp_condition
430
- c = [Static.new("hi"), Dynamic.new(:action, :condition => /^[a-z]+$/)]
431
- go c
432
-
433
- assert_equal '/hi/index', execute({:action => 'index'}, {:action => 'index'})
434
- assert_nil execute({:action => 'fox5'}, {:action => 'index'})
435
- assert_nil execute({:action => 'something_is_up'}, {:action => 'index'})
436
- assert_nil execute({}, {:action => 'list people'})
437
- assert_equal '/hi/abunchofcharacter', execute({:action => 'abunchofcharacter'}, {})
438
- assert_nil execute({}, {})
439
- end
440
-
441
- def test_dynamic_with_default_and_regexp_condition
442
- c = [Static.new("hi"), Dynamic.new(:action, :default => 'index', :condition => /^[a-z]+$/)]
443
- go c
444
-
445
- assert_equal '/hi', execute({:action => 'index'}, {:action => 'index'})
446
- assert_nil execute({:action => 'fox5'}, {:action => 'index'})
447
- assert_nil execute({:action => 'something_is_up'}, {:action => 'index'})
448
- assert_nil execute({}, {:action => 'list people'})
449
- assert_equal '/hi/abunchofcharacter', execute({:action => 'abunchofcharacter'}, {})
450
- assert_equal '/hi', execute({}, {})
451
- end
452
-
453
- def test_path
454
- c = [Static.new("hi"), Path.new(:file)]
455
- go c
456
-
457
- assert_equal '/hi', execute({:file => []}, {})
458
- assert_equal '/hi/books/agile_rails_dev.pdf', execute({:file => %w(books agile_rails_dev.pdf)}, {})
459
- assert_equal '/hi/books/development%26whatever/agile_rails_dev.pdf', execute({:file => %w(books development&whatever agile_rails_dev.pdf)}, {})
460
-
461
- assert_equal '/hi', execute({:file => ''}, {})
462
- assert_equal '/hi/books/agile_rails_dev.pdf', execute({:file => 'books/agile_rails_dev.pdf'}, {})
463
- assert_equal '/hi/books/development%26whatever/agile_rails_dev.pdf', execute({:file => 'books/development&whatever/agile_rails_dev.pdf'}, {})
464
- end
465
-
466
- def test_controller
467
- c = [Static.new("hi"), Controller.new(:controller)]
468
- go c
469
-
470
- assert_nil execute({}, {})
471
- assert_equal '/hi/content', execute({:controller => 'content'}, {})
472
- assert_equal '/hi/admin/user', execute({:controller => 'admin/user'}, {})
473
- assert_equal '/hi/content', execute({}, {:controller => 'content'})
474
- assert_equal '/hi/admin/user', execute({}, {:controller => 'admin/user'})
475
- end
476
-
477
- def test_controller_with_regexp
478
- c = [Static.new("hi"), Controller.new(:controller, :condition => /^admin\/.+$/)]
479
- go c
480
-
481
- assert_nil execute({}, {})
482
- assert_nil execute({:controller => 'content'}, {})
483
- assert_equal '/hi/admin/user', execute({:controller => 'admin/user'}, {})
484
- assert_nil execute({}, {:controller => 'content'})
485
- assert_equal '/hi/admin/user', execute({}, {:controller => 'admin/user'})
486
- end
487
-
488
- def test_standard_route(time = ::RunTimeTests)
489
- c = [Controller.new(:controller), Dynamic.new(:action, :default => 'index'), Dynamic.new(:id, :default => nil)]
490
- go c
491
-
492
- # Make sure we get the right answers
493
- assert_equal('/content', execute({:action => 'index'}, {:controller => 'content', :action => 'list'}))
494
- assert_equal('/content/list', execute({:action => 'list'}, {:controller => 'content', :action => 'index'}))
495
- assert_equal('/content/show/10', execute({:action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}))
496
-
497
- assert_equal('/admin/user', execute({:action => 'index'}, {:controller => 'admin/user', :action => 'list'}))
498
- assert_equal('/admin/user/list', execute({:action => 'list'}, {:controller => 'admin/user', :action => 'index'}))
499
- assert_equal('/admin/user/show/10', execute({:action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}))
500
-
501
- if time
502
- GC.start
503
- n = 1000
504
- time = Benchmark.realtime do n.times {
505
- execute({:action => 'index'}, {:controller => 'content', :action => 'list'})
506
- execute({:action => 'list'}, {:controller => 'content', :action => 'index'})
507
- execute({:action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'})
508
-
509
- execute({:action => 'index'}, {:controller => 'admin/user', :action => 'list'})
510
- execute({:action => 'list'}, {:controller => 'admin/user', :action => 'index'})
511
- execute({:action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'})
512
- } end
513
- time -= Benchmark.realtime do n.times { } end
514
-
515
- puts "\n\nGeneration:"
516
- per_url = time / (n * 6)
517
-
518
- puts "#{per_url * 1000} ms/url"
519
- puts "#{1 / per_url} urls/s\n\n"
520
- end
521
- end
522
-
523
- def test_default_route
524
- g.if(g.check_conditions(:controller => 'content', :action => 'welcome')) { go [] }
525
-
526
- assert_nil execute({:controller => 'foo', :action => 'welcome'}, {})
527
- assert_nil execute({:controller => 'content', :action => 'elcome'}, {})
528
- assert_nil execute({:action => 'elcome'}, {:controller => 'content'})
529
-
530
- assert_equal '/', execute({:controller => 'content', :action => 'welcome'}, {})
531
- assert_equal '/', execute({:action => 'welcome'}, {:controller => 'content'})
532
- assert_equal '/', execute({:action => 'welcome', :id => '10'}, {:controller => 'content'})
533
- end
534
- end
535
-
536
- class RouteTests < Test::Unit::TestCase
537
-
538
- def route(*args)
539
- @route = ::ActionController::Routing::Route.new(*args) unless args.empty?
540
- return @route
541
- end
542
-
543
- def rec(path, show = false)
544
- path = path.split('/') if path.is_a? String
545
- index = 0
546
- source = route.write_recognition.to_s
547
- puts "\n\n#{source}\n\n" if show
548
- r = eval(source)
549
- r ? r.symbolize_keys : r
550
- end
551
- def gen(options, recall = nil, show = false)
552
- recall ||= options.dup
553
-
554
- expire_on = ::ActionController::Routing.expiry_hash(options, recall)
555
- hash = merged = recall.merge(options)
556
- not_expired = true
557
-
558
- source = route.write_generation.to_s
559
- puts "\n\n#{source}\n\n" if show
560
- eval(source)
561
-
562
- end
563
-
564
- def test_static
565
- route 'hello/world', :known => 'known_value', :controller => 'content', :action => 'index'
566
-
567
- assert_nil rec('hello/turn')
568
- assert_nil rec('turn/world')
569
- assert_equal(
570
- {:known => 'known_value', :controller => ::ContentController, :action => 'index'},
571
- rec('hello/world')
572
- )
573
-
574
- assert_nil gen(:known => 'foo')
575
- assert_nil gen({})
576
- assert_equal '/hello/world', gen(:known => 'known_value', :controller => 'content', :action => 'index')
577
- assert_equal '/hello/world', gen(:known => 'known_value', :extra => 'hi', :controller => 'content', :action => 'index')
578
- assert_equal [:extra], route.extra_keys(:known => 'known_value', :extra => 'hi')
579
- end
580
-
581
- def test_dynamic
582
- route 'hello/:name', :controller => 'content', :action => 'show_person'
583
-
584
- assert_nil rec('hello')
585
- assert_nil rec('foo/bar')
586
- assert_equal({:controller => ::ContentController, :action => 'show_person', :name => 'rails'}, rec('hello/rails'))
587
- assert_equal({:controller => ::ContentController, :action => 'show_person', :name => 'Nicholas Seckar'}, rec('hello/Nicholas+Seckar'))
588
-
589
- assert_nil gen(:controller => 'content', :action => 'show_dude', :name => 'rails')
590
- assert_nil gen(:controller => 'content', :action => 'show_person')
591
- assert_nil gen(:controller => 'admin/user', :action => 'show_person', :name => 'rails')
592
- assert_equal '/hello/rails', gen(:controller => 'content', :action => 'show_person', :name => 'rails')
593
- assert_equal '/hello/Nicholas+Seckar', gen(:controller => 'content', :action => 'show_person', :name => 'Nicholas Seckar')
594
- end
595
-
596
- def test_typical
597
- route ':controller/:action/:id', :action => 'index', :id => nil
598
- assert_nil rec('hello')
599
- assert_nil rec('foo bar')
600
- assert_equal({:controller => ::ContentController, :action => 'index'}, rec('content'))
601
- assert_equal({:controller => ::Admin::UserController, :action => 'index'}, rec('admin/user'))
602
-
603
- assert_equal({:controller => ::Admin::UserController, :action => 'index'}, rec('admin/user/index'))
604
- assert_equal({:controller => ::Admin::UserController, :action => 'list'}, rec('admin/user/list'))
605
- assert_equal({:controller => ::Admin::UserController, :action => 'show', :id => '10'}, rec('admin/user/show/10'))
606
-
607
- assert_equal({:controller => ::ContentController, :action => 'list'}, rec('content/list'))
608
- assert_equal({:controller => ::ContentController, :action => 'show', :id => '10'}, rec('content/show/10'))
609
-
610
-
611
- assert_equal '/content', gen(:controller => 'content', :action => 'index')
612
- assert_equal '/content/list', gen(:controller => 'content', :action => 'list')
613
- assert_equal '/content/show/10', gen(:controller => 'content', :action => 'show', :id => '10')
614
-
615
- assert_equal '/admin/user', gen(:controller => 'admin/user', :action => 'index')
616
- assert_equal '/admin/user', gen(:controller => 'admin/user')
617
- assert_equal '/admin/user', gen({:controller => 'admin/user'}, {:controller => 'content', :action => 'list', :id => '10'})
618
- assert_equal '/admin/user/show/10', gen(:controller => 'admin/user', :action => 'show', :id => '10')
12
+ def warn(msg)
13
+ (@warn_output ||= []) << msg
619
14
  end
620
15
  end
621
16
 
622
- class RouteSetTests < Test::Unit::TestCase
17
+ class LegacyRouteSetTests < Test::Unit::TestCase
623
18
  attr_reader :rs
624
19
  def setup
625
20
  @rs = ::ActionController::Routing::RouteSet.new
626
21
  @rs.draw {|m| m.connect ':controller/:action/:id' }
627
- ::ActionController::Routing::NamedRoutes.clear
22
+ ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed)
628
23
  end
629
24
 
630
25
  def test_default_setup
631
- assert_equal({:controller => ::ContentController, :action => 'index'}.stringify_keys, rs.recognize_path(%w(content)))
632
- assert_equal({:controller => ::ContentController, :action => 'list'}.stringify_keys, rs.recognize_path(%w(content list)))
633
- assert_equal({:controller => ::ContentController, :action => 'show', :id => '10'}.stringify_keys, rs.recognize_path(%w(content show 10)))
26
+ assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/content"))
27
+ assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/content/list"))
28
+ assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/content/show/10"))
634
29
 
635
- assert_equal({:controller => ::Admin::UserController, :action => 'show', :id => '10'}.stringify_keys, rs.recognize_path(%w(admin user show 10)))
30
+ assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
636
31
 
637
- assert_equal ['/admin/user/show/10', []], rs.generate({:controller => 'admin/user', :action => 'show', :id => 10})
32
+ assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10)
638
33
 
639
- assert_equal ['/admin/user/show', []], rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
640
- assert_equal ['/admin/user/list/10', []], rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'})
34
+ assert_equal '/admin/user/show', rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
35
+ assert_equal '/admin/user/list/10', rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'})
641
36
 
642
- assert_equal ['/admin/stuff', []], rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
643
- assert_equal ['/stuff', []], rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
37
+ assert_equal '/admin/stuff', rs.generate({:controller => 'stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
38
+ assert_equal '/stuff', rs.generate({:controller => '/stuff'}, {:controller => 'admin/user', :action => 'list', :id => '10'})
644
39
  end
645
40
 
646
41
  def test_ignores_leading_slash
@@ -654,12 +49,12 @@ class RouteSetTests < Test::Unit::TestCase
654
49
  GC.start
655
50
  rectime = Benchmark.realtime do
656
51
  n.times do
657
- rs.recognize_path(%w(content))
658
- rs.recognize_path(%w(content list))
659
- rs.recognize_path(%w(content show 10))
660
- rs.recognize_path(%w(admin user))
661
- rs.recognize_path(%w(admin user list))
662
- rs.recognize_path(%w(admin user show 10))
52
+ rs.recognize_path("content")
53
+ rs.recognize_path("content/list")
54
+ rs.recognize_path("content/show/10")
55
+ rs.recognize_path("admin/user")
56
+ rs.recognize_path("admin/user/list")
57
+ rs.recognize_path("admin/user/show/10")
663
58
  end
664
59
  end
665
60
  puts "\n\nRecognition (RouteSet):"
@@ -703,86 +98,105 @@ class RouteSetTests < Test::Unit::TestCase
703
98
  end
704
99
  end
705
100
 
706
- def test_route_generating_string_literal_in_comparison_warning
707
- old_stderr = $stderr
708
- $stderr = StringIO.new
101
+ def test_route_with_regexp_for_controller
709
102
  rs.draw do |map|
710
- map.connect 'subscriptions/:action/:subscription_type', :controller => "subscriptions"
103
+ map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/
104
+ map.connect ':controller/:action/:id'
711
105
  end
712
- assert_equal "", $stderr.string
713
- ensure
714
- $stderr = old_stderr
106
+ assert_equal({:controller => "admin/user", :admintoken => "foo", :action => "index"},
107
+ rs.recognize_path("/admin/user/foo"))
108
+ assert_equal({:controller => "content", :action => "foo"}, rs.recognize_path("/content/foo"))
109
+ assert_equal '/admin/user/foo', rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index")
110
+ assert_equal '/content/foo', rs.generate(:controller => "content", :action => "foo")
715
111
  end
716
112
 
717
- def test_route_with_regexp_for_controller
113
+ def test_route_with_regexp_and_dot
718
114
  rs.draw do |map|
719
- map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/
720
- map.connect ':controller/:action/:id'
115
+ map.connect ':controller/:action/:file',
116
+ :controller => /admin|user/,
117
+ :action => /upload|download/,
118
+ :defaults => {:file => nil},
119
+ :requirements => {:file => %r{[^/]+(\.[^/]+)?}}
721
120
  end
722
- assert_equal({:controller => ::Admin::UserController, :admintoken => "foo", :action => "index"}.stringify_keys,
723
- rs.recognize_path(%w(admin user foo)))
724
- assert_equal({:controller => ::ContentController, :action => "foo"}.stringify_keys,
725
- rs.recognize_path(%w(content foo)))
726
- assert_equal ['/admin/user/foo', []], rs.generate(:controller => "admin/user", :admintoken => "foo", :action => "index")
727
- assert_equal ['/content/foo',[]], rs.generate(:controller => "content", :action => "foo")
121
+ # Without a file extension
122
+ assert_equal '/user/download/file',
123
+ rs.generate(:controller => "user", :action => "download", :file => "file")
124
+ assert_equal(
125
+ {:controller => "user", :action => "download", :file => "file"},
126
+ rs.recognize_path("/user/download/file"))
127
+
128
+ # Now, let's try a file with an extension, really a dot (.)
129
+ assert_equal '/user/download/file.jpg',
130
+ rs.generate(
131
+ :controller => "user", :action => "download", :file => "file.jpg")
132
+ assert_equal(
133
+ {:controller => "user", :action => "download", :file => "file.jpg"},
134
+ rs.recognize_path("/user/download/file.jpg"))
728
135
  end
729
136
 
730
137
  def test_basic_named_route
731
- rs.home '', :controller => 'content', :action => 'list'
732
- x = setup_for_named_route
733
- assert_equal({:controller => '/content', :action => 'list'},
734
- x.new.send(:home_url))
138
+ rs.add_named_route :home, '', :controller => 'content', :action => 'list'
139
+ x = setup_for_named_route.new
140
+ assert_equal({:controller => 'content', :action => 'list', :use_route => :home, :only_path => false},
141
+ x.send(:home_url))
735
142
  end
736
143
 
737
144
  def test_named_route_with_option
738
- rs.page 'page/:title', :controller => 'content', :action => 'show_page'
739
- x = setup_for_named_route
740
- assert_equal({:controller => '/content', :action => 'show_page', :title => 'new stuff'},
741
- x.new.send(:page_url, :title => 'new stuff'))
145
+ rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page'
146
+ x = setup_for_named_route.new
147
+ assert_equal({:controller => 'content', :action => 'show_page', :title => 'new stuff', :use_route => :page, :only_path => false},
148
+ x.send(:page_url, :title => 'new stuff'))
742
149
  end
743
150
 
744
151
  def test_named_route_with_default
745
- rs.page 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage'
746
- x = setup_for_named_route
747
- assert_equal({:controller => '/content', :action => 'show_page', :title => 'AboutPage'},
748
- x.new.send(:page_url))
749
- assert_equal({:controller => '/content', :action => 'show_page', :title => 'AboutRails'},
750
- x.new.send(:page_url, :title => "AboutRails"))
152
+ rs.add_named_route :page, 'page/:title', :controller => 'content', :action => 'show_page', :title => 'AboutPage'
153
+ x = setup_for_named_route.new
154
+ assert_equal({:controller => 'content', :action => 'show_page', :title => 'AboutPage', :use_route => :page, :only_path => false},
155
+ x.send(:page_url))
156
+ assert_equal({:controller => 'content', :action => 'show_page', :title => 'AboutRails', :use_route => :page, :only_path => false},
157
+ x.send(:page_url, :title => "AboutRails"))
751
158
 
752
159
  end
753
160
 
161
+ def test_named_route_with_nested_controller
162
+ rs.add_named_route :users, 'admin/user', :controller => '/admin/user', :action => 'index'
163
+ x = setup_for_named_route.new
164
+ assert_equal({:controller => '/admin/user', :action => 'index', :use_route => :users, :only_path => false},
165
+ x.send(:users_url))
166
+ end
167
+
754
168
  def setup_for_named_route
755
169
  x = Class.new
756
170
  x.send(:define_method, :url_for) {|x| x}
757
- x.send :include, ::ActionController::Routing::NamedRoutes
171
+ rs.named_routes.install(x)
758
172
  x
759
173
  end
760
174
 
761
175
  def test_named_route_without_hash
762
176
  rs.draw do |map|
763
- rs.normal ':controller/:action/:id'
177
+ map.normal ':controller/:action/:id'
764
178
  end
765
179
  end
766
180
 
767
181
  def test_named_route_with_regexps
768
182
  rs.draw do |map|
769
- rs.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show',
770
- :year => /^\d+$/, :month => /^\d+$/, :day => /^\d+$/
771
- rs.connect ':controller/:action/:id'
183
+ map.article 'page/:year/:month/:day/:title', :controller => 'page', :action => 'show',
184
+ :year => /\d+/, :month => /\d+/, :day => /\d+/
185
+ map.connect ':controller/:action/:id'
772
186
  end
773
- x = setup_for_named_route
187
+ x = setup_for_named_route.new
774
188
  assert_equal(
775
- {:controller => '/page', :action => 'show', :title => 'hi'},
776
- x.new.send(:article_url, :title => 'hi')
189
+ {:controller => 'page', :action => 'show', :title => 'hi', :use_route => :article, :only_path => false},
190
+ x.send(:article_url, :title => 'hi')
777
191
  )
778
192
  assert_equal(
779
- {:controller => '/page', :action => 'show', :title => 'hi', :day => 10, :year => 2005, :month => 6},
780
- x.new.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
193
+ {:controller => 'page', :action => 'show', :title => 'hi', :day => 10, :year => 2005, :month => 6, :use_route => :article, :only_path => false},
194
+ x.send(:article_url, :title => 'hi', :day => 10, :year => 2005, :month => 6)
781
195
  )
782
196
  end
783
197
 
784
198
  def test_changing_controller
785
- assert_equal ['/admin/stuff/show/10', []], rs.generate(
199
+ assert_equal '/admin/stuff/show/10', rs.generate(
786
200
  {:controller => 'stuff', :action => 'show', :id => 10},
787
201
  {:controller => 'admin/user', :action => 'index'}
788
202
  )
@@ -790,260 +204,1555 @@ class RouteSetTests < Test::Unit::TestCase
790
204
 
791
205
  def test_paths_escaped
792
206
  rs.draw do |map|
793
- rs.path 'file/*path', :controller => 'content', :action => 'show_file'
794
- rs.connect ':controller/:action/:id'
207
+ map.path 'file/*path', :controller => 'content', :action => 'show_file'
208
+ map.connect ':controller/:action/:id'
795
209
  end
796
- results = rs.recognize_path %w(file hello+world how+are+you%3F)
210
+ results = rs.recognize_path "/file/hello+world/how+are+you%3F"
797
211
  assert results, "Recognition should have succeeded"
798
- assert_equal ['hello world', 'how are you?'], results['path']
212
+ assert_equal ['hello world', 'how are you?'], results[:path]
799
213
 
800
- results = rs.recognize_path %w(file)
214
+ results = rs.recognize_path "/file"
801
215
  assert results, "Recognition should have succeeded"
802
- assert_equal [], results['path']
216
+ assert_equal [], results[:path]
803
217
  end
804
218
 
805
219
  def test_non_controllers_cannot_be_matched
806
- rs.draw do
807
- rs.connect ':controller/:action/:id'
220
+ rs.draw do |map|
221
+ map.connect ':controller/:action/:id'
808
222
  end
809
- assert_nil rs.recognize_path(%w(not_a show 10)), "Shouldn't recognize non-controllers as controllers!"
223
+ assert_raises(ActionController::RoutingError) { rs.recognize_path("/not_a/show/10") }
810
224
  end
811
225
 
812
226
  def test_paths_do_not_accept_defaults
813
227
  assert_raises(ActionController::RoutingError) do
814
228
  rs.draw do |map|
815
- rs.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default)
816
- rs.connect ':controller/:action/:id'
229
+ map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => %w(fake default)
230
+ map.connect ':controller/:action/:id'
817
231
  end
818
232
  end
819
233
 
820
234
  rs.draw do |map|
821
- rs.path 'file/*path', :controller => 'content', :action => 'show_file', :path => []
822
- rs.connect ':controller/:action/:id'
235
+ map.path 'file/*path', :controller => 'content', :action => 'show_file', :path => []
236
+ map.connect ':controller/:action/:id'
823
237
  end
824
238
  end
825
-
239
+
240
+ def test_dynamic_path_allowed
241
+ rs.draw do |map|
242
+ map.connect '*path', :controller => 'content', :action => 'show_file'
243
+ end
244
+
245
+ assert_equal '/pages/boo', rs.generate(:controller => 'content', :action => 'show_file', :path => %w(pages boo))
246
+ end
247
+
248
+ def test_dynamic_recall_paths_allowed
249
+ rs.draw do |map|
250
+ map.connect '*path', :controller => 'content', :action => 'show_file'
251
+ end
252
+
253
+ recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo))
254
+ assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path)
255
+ end
256
+
826
257
  def test_backwards
827
258
  rs.draw do |map|
828
- rs.connect 'page/:id/:action', :controller => 'pages', :action => 'show'
829
- rs.connect ':controller/:action/:id'
259
+ map.connect 'page/:id/:action', :controller => 'pages', :action => 'show'
260
+ map.connect ':controller/:action/:id'
830
261
  end
831
262
 
832
- assert_equal ['/page/20', []], rs.generate({:id => 20}, {:controller => 'pages'})
833
- assert_equal ['/page/20', []], rs.generate(:controller => 'pages', :id => 20, :action => 'show')
834
- assert_equal ['/pages/boo', []], rs.generate(:controller => 'pages', :action => 'boo')
263
+ assert_equal '/page/20', rs.generate({:id => 20}, {:controller => 'pages', :action => 'show'})
264
+ assert_equal '/page/20', rs.generate(:controller => 'pages', :id => 20, :action => 'show')
265
+ assert_equal '/pages/boo', rs.generate(:controller => 'pages', :action => 'boo')
835
266
  end
836
267
 
837
268
  def test_route_with_fixnum_default
838
269
  rs.draw do |map|
839
- rs.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
840
- rs.connect ':controller/:action/:id'
270
+ map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
271
+ map.connect ':controller/:action/:id'
841
272
  end
842
273
 
843
- assert_equal ['/page', []], rs.generate(:controller => 'content', :action => 'show_page')
844
- assert_equal ['/page', []], rs.generate(:controller => 'content', :action => 'show_page', :id => 1)
845
- assert_equal ['/page', []], rs.generate(:controller => 'content', :action => 'show_page', :id => '1')
846
- assert_equal ['/page/10', []], rs.generate(:controller => 'content', :action => 'show_page', :id => 10)
847
-
848
- ctrl = ::ContentController
274
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page')
275
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => 1)
276
+ assert_equal '/page', rs.generate(:controller => 'content', :action => 'show_page', :id => '1')
277
+ assert_equal '/page/10', rs.generate(:controller => 'content', :action => 'show_page', :id => 10)
849
278
 
850
- assert_equal({'controller' => ctrl, 'action' => 'show_page', 'id' => 1}, rs.recognize_path(%w(page)))
851
- assert_equal({'controller' => ctrl, 'action' => 'show_page', 'id' => '1'}, rs.recognize_path(%w(page 1)))
852
- assert_equal({'controller' => ctrl, 'action' => 'show_page', 'id' => '10'}, rs.recognize_path(%w(page 10)))
279
+ assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page"))
280
+ assert_equal({:controller => "content", :action => 'show_page', :id => '1'}, rs.recognize_path("/page/1"))
281
+ assert_equal({:controller => "content", :action => 'show_page', :id => '10'}, rs.recognize_path("/page/10"))
853
282
  end
854
283
 
284
+ # For newer revision
285
+ def test_route_with_text_default
286
+ rs.draw do |map|
287
+ map.connect 'page/:id', :controller => 'content', :action => 'show_page', :id => 1
288
+ map.connect ':controller/:action/:id'
289
+ end
290
+
291
+ assert_equal '/page/foo', rs.generate(:controller => 'content', :action => 'show_page', :id => 'foo')
292
+ assert_equal({:controller => "content", :action => 'show_page', :id => 'foo'}, rs.recognize_path("/page/foo"))
293
+
294
+ token = "\321\202\320\265\320\272\321\201\321\202" # 'text' in russian
295
+ escaped_token = CGI::escape(token)
296
+
297
+ assert_equal '/page/' + escaped_token, rs.generate(:controller => 'content', :action => 'show_page', :id => token)
298
+ assert_equal({:controller => "content", :action => 'show_page', :id => token}, rs.recognize_path("/page/#{escaped_token}"))
299
+ end
300
+
855
301
  def test_action_expiry
856
- assert_equal ['/content', []], rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
302
+ assert_equal '/content', rs.generate({:controller => 'content'}, {:controller => 'content', :action => 'show'})
857
303
  end
858
304
 
859
305
  def test_recognition_with_uppercase_controller_name
860
- assert_equal({'controller' => ::ContentController, 'action' => 'index'}, rs.recognize_path(%w(Content)))
861
- assert_equal({'controller' => ::ContentController, 'action' => 'list'}, rs.recognize_path(%w(Content list)))
862
- assert_equal({'controller' => ::ContentController, 'action' => 'show', 'id' => '10'}, rs.recognize_path(%w(Content show 10)))
306
+ assert_equal({:controller => "content", :action => 'index'}, rs.recognize_path("/Content"))
307
+ assert_equal({:controller => "content", :action => 'list'}, rs.recognize_path("/ConTent/list"))
308
+ assert_equal({:controller => "content", :action => 'show', :id => '10'}, rs.recognize_path("/CONTENT/show/10"))
863
309
 
864
- assert_equal({'controller' => ::Admin::NewsFeedController, 'action' => 'index'}, rs.recognize_path(%w(Admin NewsFeed)))
865
- assert_equal({'controller' => ::Admin::NewsFeedController, 'action' => 'index'}, rs.recognize_path(%w(Admin News_Feed)))
310
+ # these used to work, before the routes rewrite, but support for this was pulled in the new version...
311
+ #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/NewsFeed"))
312
+ #assert_equal({'controller' => "admin/news_feed", 'action' => 'index'}, rs.recognize_path("Admin/News_Feed"))
866
313
  end
314
+
315
+ def test_requirement_should_prevent_optional_id
316
+ rs.draw do |map|
317
+ map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
318
+ end
867
319
 
320
+ assert_equal '/post/10', rs.generate(:controller => 'post', :action => 'show', :id => 10)
321
+
322
+ assert_raises ActionController::RoutingError do
323
+ rs.generate(:controller => 'post', :action => 'show')
324
+ end
325
+ end
326
+
868
327
  def test_both_requirement_and_optional
869
- rs.draw do
870
- rs.blog('test/:year', :controller => 'post', :action => 'show',
328
+ rs.draw do |map|
329
+ map.blog('test/:year', :controller => 'post', :action => 'show',
871
330
  :defaults => { :year => nil },
872
331
  :requirements => { :year => /\d{4}/ }
873
332
  )
874
- rs.connect ':controller/:action/:id'
333
+ map.connect ':controller/:action/:id'
875
334
  end
876
335
 
877
- assert_equal ['/test', []], rs.generate(:controller => 'post', :action => 'show')
878
- assert_equal ['/test', []], rs.generate(:controller => 'post', :action => 'show', :year => nil)
336
+ assert_equal '/test', rs.generate(:controller => 'post', :action => 'show')
337
+ assert_equal '/test', rs.generate(:controller => 'post', :action => 'show', :year => nil)
879
338
 
880
- x = setup_for_named_route
881
- assert_equal({:controller => '/post', :action => 'show'},
882
- x.new.send(:blog_url))
339
+ x = setup_for_named_route.new
340
+ assert_equal({:controller => 'post', :action => 'show', :use_route => :blog, :only_path => false},
341
+ x.send(:blog_url))
883
342
  end
884
343
 
885
344
  def test_set_to_nil_forgets
886
- rs.draw do
887
- rs.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil
888
- rs.connect ':controller/:action/:id'
345
+ rs.draw do |map|
346
+ map.connect 'pages/:year/:month/:day', :controller => 'content', :action => 'list_pages', :month => nil, :day => nil
347
+ map.connect ':controller/:action/:id'
889
348
  end
890
349
 
891
- assert_equal ['/pages/2005', []],
350
+ assert_equal '/pages/2005',
892
351
  rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005)
893
- assert_equal ['/pages/2005/6', []],
352
+ assert_equal '/pages/2005/6',
894
353
  rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6)
895
- assert_equal ['/pages/2005/6/12', []],
354
+ assert_equal '/pages/2005/6/12',
896
355
  rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6, :day => 12)
897
356
 
898
- assert_equal ['/pages/2005/6/4', []],
357
+ assert_equal '/pages/2005/6/4',
899
358
  rs.generate({:day => 4}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
900
359
 
901
- assert_equal ['/pages/2005/6', []],
360
+ assert_equal '/pages/2005/6',
902
361
  rs.generate({:day => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
903
362
 
904
- assert_equal ['/pages/2005', []],
363
+ assert_equal '/pages/2005',
905
364
  rs.generate({:day => nil, :month => nil}, {:controller => 'content', :action => 'list_pages', :year => '2005', :month => '6', :day => '12'})
906
365
  end
907
366
 
908
367
  def test_url_with_no_action_specified
909
- rs.draw do
910
- rs.connect '', :controller => 'content'
911
- rs.connect ':controller/:action/:id'
368
+ rs.draw do |map|
369
+ map.connect '', :controller => 'content'
370
+ map.connect ':controller/:action/:id'
912
371
  end
913
372
 
914
- assert_equal ['/', []], rs.generate(:controller => 'content', :action => 'index')
915
- assert_equal ['/', []], rs.generate(:controller => 'content')
373
+ assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
374
+ assert_equal '/', rs.generate(:controller => 'content')
916
375
  end
917
376
 
918
377
  def test_named_url_with_no_action_specified
919
- rs.draw do
920
- rs.root '', :controller => 'content'
921
- rs.connect ':controller/:action/:id'
378
+ rs.draw do |map|
379
+ map.home '', :controller => 'content'
380
+ map.connect ':controller/:action/:id'
922
381
  end
923
382
 
924
- assert_equal ['/', []], rs.generate(:controller => 'content', :action => 'index')
925
- assert_equal ['/', []], rs.generate(:controller => 'content')
383
+ assert_equal '/', rs.generate(:controller => 'content', :action => 'index')
384
+ assert_equal '/', rs.generate(:controller => 'content')
926
385
 
927
- x = setup_for_named_route
928
- assert_equal({:controller => '/content', :action => 'index'},
929
- x.new.send(:root_url))
386
+ x = setup_for_named_route.new
387
+ assert_equal({:controller => 'content', :action => 'index', :use_route => :home, :only_path => false},
388
+ x.send(:home_url))
930
389
  end
931
390
 
932
391
  def test_url_generated_when_forgetting_action
933
392
  [{:controller => 'content', :action => 'index'}, {:controller => 'content'}].each do |hash|
934
- rs.draw do
935
- rs.root '', hash
936
- rs.connect ':controller/:action/:id'
393
+ rs.draw do |map|
394
+ map.home '', hash
395
+ map.connect ':controller/:action/:id'
937
396
  end
938
- assert_equal ['/', []], rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'})
939
- assert_equal ['/', []], rs.generate({:controller => 'content'})
940
- assert_equal ['/content/hi', []], rs.generate({:controller => 'content', :action => 'hi'})
397
+ assert_equal '/', rs.generate({:action => nil}, {:controller => 'content', :action => 'hello'})
398
+ assert_equal '/', rs.generate({:controller => 'content'})
399
+ assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
941
400
  end
942
401
  end
943
402
 
944
403
  def test_named_route_method
945
- rs.draw do
946
- assert_raises(ArgumentError) { rs.categories 'categories', :controller => 'content', :action => 'categories' }
947
-
948
- rs.named_route :categories, 'categories', :controller => 'content', :action => 'categories'
949
- rs.connect ':controller/:action/:id'
404
+ rs.draw do |map|
405
+ map.categories 'categories', :controller => 'content', :action => 'categories'
406
+ map.connect ':controller/:action/:id'
950
407
  end
951
408
 
952
- assert_equal ['/categories', []], rs.generate(:controller => 'content', :action => 'categories')
953
- assert_equal ['/content/hi', []], rs.generate({:controller => 'content', :action => 'hi'})
409
+ assert_equal '/categories', rs.generate(:controller => 'content', :action => 'categories')
410
+ assert_equal '/content/hi', rs.generate({:controller => 'content', :action => 'hi'})
954
411
  end
955
412
 
956
- def test_named_route_helper_array
413
+ def test_named_routes_array
957
414
  test_named_route_method
958
- assert_equal [:categories_url, :hash_for_categories_url], ::ActionController::Routing::NamedRoutes::Helpers
415
+ assert_equal [:categories], rs.named_routes.names
959
416
  end
960
417
 
961
418
  def test_nil_defaults
962
- rs.draw do
963
- rs.connect 'journal',
419
+ rs.draw do |map|
420
+ map.connect 'journal',
964
421
  :controller => 'content',
965
422
  :action => 'list_journal',
966
423
  :date => nil, :user_id => nil
967
- rs.connect ':controller/:action/:id'
424
+ map.connect ':controller/:action/:id'
968
425
  end
969
426
 
970
- assert_equal ['/journal', []], rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil)
427
+ assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil)
971
428
  end
972
- end
973
429
 
974
- class ControllerComponentTest < Test::Unit::TestCase
975
-
976
- def test_traverse_to_controller_should_not_load_arbitrary_files
977
- load_path = $:.dup
978
- base = File.dirname(File.dirname(File.expand_path(__FILE__)))
979
- $: << File.join(base, 'fixtures')
980
- Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root')
981
- assert_equal nil, ActionController::Routing::ControllerComponent.traverse_to_controller(%w(dont_load pretty please))
982
- ensure
983
- $:[0..-1] = load_path
984
- Object.send :remove_const, :RAILS_ROOT
985
- end
986
-
987
- def test_traverse_should_not_trip_on_non_module_constants
988
- assert_equal nil, ActionController::Routing::ControllerComponent.traverse_to_controller(%w(admin some_constant a))
989
- end
990
-
991
- # This is evil, but people do it.
992
- def test_traverse_to_controller_should_pass_thru_classes
993
- load_path = $:.dup
994
- base = File.dirname(File.dirname(File.expand_path(__FILE__)))
995
- $: << File.join(base, 'fixtures')
996
- $: << File.join(base, 'fixtures/application_root/app/controllers')
997
- $: << File.join(base, 'fixtures/application_root/app/models')
998
- Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root')
999
- pair = ActionController::Routing::ControllerComponent.traverse_to_controller(%w(a_class_that_contains_a_controller poorly_placed))
1000
-
1001
- # Make sure the container class was loaded properly
1002
- assert defined?(AClassThatContainsAController)
1003
- assert_kind_of Class, AClassThatContainsAController
1004
- assert_equal :you_know_it, AClassThatContainsAController.is_special?
1005
-
1006
- # Make sure the controller was too
1007
- assert_kind_of Array, pair
1008
- assert_equal 2, pair[1]
1009
- klass = pair.first
1010
- assert_kind_of Class, klass
1011
- assert_equal :decidedly_so, klass.is_evil?
1012
- assert klass.ancestors.include?(ActionController::Base)
1013
- assert defined?(AClassThatContainsAController::PoorlyPlacedController)
1014
- assert_equal klass, AClassThatContainsAController::PoorlyPlacedController
430
+ def setup_request_method_routes_for(method)
431
+ @request = ActionController::TestRequest.new
432
+ @request.env["REQUEST_METHOD"] = method
433
+ @request.request_uri = "/match"
434
+
435
+ rs.draw do |r|
436
+ r.connect '/match', :controller => 'books', :action => 'get', :conditions => { :method => :get }
437
+ r.connect '/match', :controller => 'books', :action => 'post', :conditions => { :method => :post }
438
+ r.connect '/match', :controller => 'books', :action => 'put', :conditions => { :method => :put }
439
+ r.connect '/match', :controller => 'books', :action => 'delete', :conditions => { :method => :delete }
440
+ end
441
+ end
442
+
443
+ %w(GET POST PUT DELETE).each do |request_method|
444
+ define_method("test_request_method_recognized_with_#{request_method}") do
445
+ begin
446
+ Object.const_set(:BooksController, Class.new(ActionController::Base))
447
+
448
+ setup_request_method_routes_for(request_method)
449
+
450
+ assert_nothing_raised { rs.recognize(@request) }
451
+ assert_equal request_method.downcase, @request.path_parameters[:action]
452
+ ensure
453
+ Object.send(:remove_const, :BooksController) rescue nil
454
+ end
455
+ end
456
+ end
457
+
458
+ def test_subpath_recognized
459
+ Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
460
+
461
+ rs.draw do |r|
462
+ r.connect '/books/:id;edit', :controller => 'subpath_books', :action => 'edit'
463
+ r.connect '/items/:id;:action', :controller => 'subpath_books'
464
+ r.connect '/posts/new;:action', :controller => 'subpath_books'
465
+ r.connect '/posts/:id', :controller => 'subpath_books', :action => "show"
466
+ end
467
+
468
+ hash = rs.recognize_path "/books/17;edit"
469
+ assert_not_nil hash
470
+ assert_equal %w(subpath_books 17 edit), [hash[:controller], hash[:id], hash[:action]]
471
+
472
+ hash = rs.recognize_path "/items/3;complete"
473
+ assert_not_nil hash
474
+ assert_equal %w(subpath_books 3 complete), [hash[:controller], hash[:id], hash[:action]]
475
+
476
+ hash = rs.recognize_path "/posts/new;preview"
477
+ assert_not_nil hash
478
+ assert_equal %w(subpath_books preview), [hash[:controller], hash[:action]]
479
+
480
+ hash = rs.recognize_path "/posts/7"
481
+ assert_not_nil hash
482
+ assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
1015
483
  ensure
1016
- $:[0..-1] = load_path
1017
- Object.send :remove_const, :RAILS_ROOT
1018
- end
1019
-
1020
- def test_traverse_to_nested_controller
1021
- load_path = $:.dup
1022
- base = File.dirname(File.dirname(File.expand_path(__FILE__)))
1023
- $: << File.join(base, 'fixtures')
1024
- $: << File.join(base, 'fixtures/application_root/app/controllers')
1025
- Object.send :const_set, :RAILS_ROOT, File.join(base, 'fixtures/application_root')
1026
- pair = ActionController::Routing::ControllerComponent.traverse_to_controller(%w(module_that_holds_controllers nested))
1027
-
1028
- assert_not_equal nil, pair
1029
-
1030
- # Make sure that we created a module for the dir
1031
- assert defined?(ModuleThatHoldsControllers)
1032
- assert_kind_of Module, ModuleThatHoldsControllers
1033
-
1034
- # Make sure the controller is ok
1035
- assert_kind_of Array, pair
1036
- assert_equal 2, pair[1]
1037
- klass = pair.first
1038
- assert_kind_of Class, klass
1039
- assert klass.ancestors.include?(ActionController::Base)
1040
- assert defined?(ModuleThatHoldsControllers::NestedController)
1041
- assert_equal klass, ModuleThatHoldsControllers::NestedController
484
+ Object.send(:remove_const, :SubpathBooksController) rescue nil
485
+ end
486
+
487
+ def test_subpath_generated
488
+ Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
489
+
490
+ rs.draw do |r|
491
+ r.connect '/books/:id;edit', :controller => 'subpath_books', :action => 'edit'
492
+ r.connect '/items/:id;:action', :controller => 'subpath_books'
493
+ r.connect '/posts/new;:action', :controller => 'subpath_books'
494
+ end
495
+
496
+ assert_equal "/books/7;edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit")
497
+ assert_equal "/items/15;complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete")
498
+ assert_equal "/posts/new;preview", rs.generate(:controller => "subpath_books", :action => "preview")
1042
499
  ensure
1043
- $:[0..-1] = load_path
1044
- Object.send :remove_const, :RAILS_ROOT
500
+ Object.send(:remove_const, :SubpathBooksController) rescue nil
501
+ end
502
+ end
503
+
504
+ class SegmentTest < Test::Unit::TestCase
505
+
506
+ def test_first_segment_should_interpolate_for_structure
507
+ s = ROUTING::Segment.new
508
+ def s.interpolation_statement(array) 'hello' end
509
+ assert_equal 'hello', s.continue_string_structure([])
510
+ end
511
+
512
+ def test_interpolation_statement
513
+ s = ROUTING::StaticSegment.new
514
+ s.value = "Hello"
515
+ assert_equal "Hello", eval(s.interpolation_statement([]))
516
+ assert_equal "HelloHello", eval(s.interpolation_statement([s]))
517
+
518
+ s2 = ROUTING::StaticSegment.new
519
+ s2.value = "-"
520
+ assert_equal "Hello-Hello", eval(s.interpolation_statement([s, s2]))
521
+
522
+ s3 = ROUTING::StaticSegment.new
523
+ s3.value = "World"
524
+ assert_equal "Hello-World", eval(s3.interpolation_statement([s, s2]))
525
+ end
526
+
527
+ end
528
+
529
+ class StaticSegmentTest < Test::Unit::TestCase
530
+
531
+ def test_interpolation_chunk_should_respect_raw
532
+ s = ROUTING::StaticSegment.new
533
+ s.value = 'Hello/World'
534
+ assert ! s.raw?
535
+ assert_equal 'Hello/World', CGI.unescape(s.interpolation_chunk)
536
+
537
+ s.raw = true
538
+ assert s.raw?
539
+ assert_equal 'Hello/World', s.interpolation_chunk
540
+ end
541
+
542
+ def test_regexp_chunk_should_escape_specials
543
+ s = ROUTING::StaticSegment.new
544
+
545
+ s.value = 'Hello*World'
546
+ assert_equal 'Hello\*World', s.regexp_chunk
547
+
548
+ s.value = 'HelloWorld'
549
+ assert_equal 'HelloWorld', s.regexp_chunk
550
+ end
551
+
552
+ def test_regexp_chunk_should_add_question_mark_for_optionals
553
+ s = ROUTING::StaticSegment.new
554
+ s.value = "/"
555
+ s.is_optional = true
556
+ assert_equal "/?", s.regexp_chunk
557
+
558
+ s.value = "hello"
559
+ assert_equal "(?:hello)?", s.regexp_chunk
1045
560
  end
1046
561
 
1047
562
  end
1048
563
 
564
+ class DynamicSegmentTest < Test::Unit::TestCase
565
+
566
+ def segment
567
+ unless @segment
568
+ @segment = ROUTING::DynamicSegment.new
569
+ @segment.key = :a
570
+ end
571
+ @segment
572
+ end
573
+
574
+ def test_extract_value
575
+ s = ROUTING::DynamicSegment.new
576
+ s.key = :a
577
+
578
+ hash = {:a => '10', :b => '20'}
579
+ assert_equal '10', eval(s.extract_value)
580
+
581
+ hash = {:b => '20'}
582
+ assert_equal nil, eval(s.extract_value)
583
+
584
+ s.default = '20'
585
+ assert_equal '20', eval(s.extract_value)
586
+ end
587
+
588
+ def test_default_local_name
589
+ assert_equal 'a_value', segment.local_name,
590
+ "Unexpected name -- all value_check tests will fail!"
591
+ end
592
+
593
+ def test_presence_value_check
594
+ a_value = 10
595
+ assert eval(segment.value_check)
596
+ end
597
+
598
+ def test_regexp_value_check_rejects_nil
599
+ segment.regexp = /\d+/
600
+ a_value = nil
601
+ assert ! eval(segment.value_check)
602
+ end
603
+
604
+ def test_optional_regexp_value_check_should_accept_nil
605
+ segment.regexp = /\d+/
606
+ segment.is_optional = true
607
+ a_value = nil
608
+ assert eval(segment.value_check)
609
+ end
610
+
611
+ def test_regexp_value_check_rejects_no_match
612
+ segment.regexp = /\d+/
613
+
614
+ a_value = "Hello20World"
615
+ assert ! eval(segment.value_check)
616
+
617
+ a_value = "20Hi"
618
+ assert ! eval(segment.value_check)
619
+ end
620
+
621
+ def test_regexp_value_check_accepts_match
622
+ segment.regexp = /\d+/
623
+
624
+ a_value = "30"
625
+ assert eval(segment.value_check)
626
+ end
627
+
628
+ def test_value_check_fails_on_nil
629
+ a_value = nil
630
+ assert ! eval(segment.value_check)
631
+ end
632
+
633
+ def test_optional_value_needs_no_check
634
+ segment.is_optional = true
635
+ a_value = nil
636
+ assert_equal nil, segment.value_check
637
+ end
638
+
639
+ def test_regexp_value_check_should_accept_match_with_default
640
+ segment.regexp = /\d+/
641
+ segment.default = '200'
642
+
643
+ a_value = '100'
644
+ assert eval(segment.value_check)
645
+ end
646
+
647
+ def test_expiry_should_not_trigger_once_expired
648
+ expired = true
649
+ hash = merged = {:a => 2, :b => 3}
650
+ options = {:b => 3}
651
+ expire_on = Hash.new { raise 'No!!!' }
652
+
653
+ eval(segment.expiry_statement)
654
+ rescue RuntimeError
655
+ flunk "Expiry check should not have occured!"
656
+ end
657
+
658
+ def test_expiry_should_occur_according_to_expire_on
659
+ expired = false
660
+ hash = merged = {:a => 2, :b => 3}
661
+ options = {:b => 3}
662
+
663
+ expire_on = {:b => true, :a => false}
664
+ eval(segment.expiry_statement)
665
+ assert !expired
666
+ assert_equal({:a => 2, :b => 3}, hash)
667
+
668
+ expire_on = {:b => true, :a => true}
669
+ eval(segment.expiry_statement)
670
+ assert expired
671
+ assert_equal({:b => 3}, hash)
672
+ end
673
+
674
+ def test_extraction_code_should_return_on_nil
675
+ hash = merged = {:b => 3}
676
+ options = {:b => 3}
677
+ a_value = nil
678
+
679
+ # Local jump because of return inside eval.
680
+ assert_raises(LocalJumpError) { eval(segment.extraction_code) }
681
+ end
682
+
683
+ def test_extraction_code_should_return_on_mismatch
684
+ segment.regexp = /\d+/
685
+ hash = merged = {:a => 'Hi', :b => '3'}
686
+ options = {:b => '3'}
687
+ a_value = nil
688
+
689
+ # Local jump because of return inside eval.
690
+ assert_raises(LocalJumpError) { eval(segment.extraction_code) }
691
+ end
692
+
693
+ def test_extraction_code_should_accept_value_and_set_local
694
+ hash = merged = {:a => 'Hi', :b => '3'}
695
+ options = {:b => '3'}
696
+ a_value = nil
697
+ expired = true
698
+
699
+ eval(segment.extraction_code)
700
+ assert_equal 'Hi', a_value
701
+ end
702
+
703
+ def test_extraction_should_work_without_value_check
704
+ segment.default = 'hi'
705
+ hash = merged = {:b => '3'}
706
+ options = {:b => '3'}
707
+ a_value = nil
708
+ expired = true
709
+
710
+ eval(segment.extraction_code)
711
+ assert_equal 'hi', a_value
712
+ end
713
+
714
+ def test_extraction_code_should_perform_expiry
715
+ expired = false
716
+ hash = merged = {:a => 'Hi', :b => '3'}
717
+ options = {:b => '3'}
718
+ expire_on = {:a => true}
719
+ a_value = nil
720
+
721
+ eval(segment.extraction_code)
722
+ assert_equal 'Hi', a_value
723
+ assert expired
724
+ assert_equal options, hash
725
+ end
726
+
727
+ def test_interpolation_chunk_should_replace_value
728
+ a_value = 'Hi'
729
+ assert_equal a_value, eval(%("#{segment.interpolation_chunk}"))
730
+ end
731
+
732
+ def test_value_regexp_should_be_nil_without_regexp
733
+ assert_equal nil, segment.value_regexp
734
+ end
735
+
736
+ def test_value_regexp_should_match_exacly
737
+ segment.regexp = /\d+/
738
+ assert_no_match segment.value_regexp, "Hello 10 World"
739
+ assert_no_match segment.value_regexp, "Hello 10"
740
+ assert_no_match segment.value_regexp, "10 World"
741
+ assert_match segment.value_regexp, "10"
742
+ end
743
+
744
+ def test_regexp_chunk_should_return_string
745
+ segment.regexp = /\d+/
746
+ assert_kind_of String, segment.regexp_chunk
747
+ end
748
+
749
+ end
750
+
751
+ class ControllerSegmentTest < Test::Unit::TestCase
752
+
753
+ def test_regexp_should_only_match_possible_controllers
754
+ ActionController::Routing.with_controllers %w(admin/accounts admin/users account pages) do
755
+ cs = ROUTING::ControllerSegment.new :controller
756
+ regexp = %r{\A#{cs.regexp_chunk}\Z}
757
+
758
+ ActionController::Routing.possible_controllers.each do |name|
759
+ assert_match regexp, name
760
+ assert_no_match regexp, "#{name}_fake"
761
+
762
+ match = regexp.match name
763
+ assert_equal name, match[1]
764
+ end
765
+ end
766
+ end
767
+
768
+ end
769
+
770
+ class RouteTest < Test::Unit::TestCase
771
+
772
+ def setup
773
+ @route = ROUTING::Route.new
774
+ end
775
+
776
+ def slash_segment(is_optional = false)
777
+ returning ROUTING::DividerSegment.new('/') do |s|
778
+ s.is_optional = is_optional
779
+ end
780
+ end
781
+
782
+ def default_route
783
+ unless @default_route
784
+ @default_route = ROUTING::Route.new
785
+
786
+ @default_route.segments << (s = ROUTING::StaticSegment.new)
787
+ s.value = '/'
788
+ s.raw = true
789
+
790
+ @default_route.segments << (s = ROUTING::DynamicSegment.new)
791
+ s.key = :controller
792
+
793
+ @default_route.segments << slash_segment(:optional)
794
+ @default_route.segments << (s = ROUTING::DynamicSegment.new)
795
+ s.key = :action
796
+ s.default = 'index'
797
+ s.is_optional = true
798
+
799
+ @default_route.segments << slash_segment(:optional)
800
+ @default_route.segments << (s = ROUTING::DynamicSegment.new)
801
+ s.key = :id
802
+ s.is_optional = true
803
+
804
+ @default_route.segments << slash_segment(:optional)
805
+ end
806
+ @default_route
807
+ end
808
+
809
+ def test_default_route_recognition
810
+ expected = {:controller => 'accounts', :action => 'show', :id => '10'}
811
+ assert_equal expected, default_route.recognize('/accounts/show/10')
812
+ assert_equal expected, default_route.recognize('/accounts/show/10/')
813
+
814
+ expected[:id] = 'jamis'
815
+ assert_equal expected, default_route.recognize('/accounts/show/jamis/')
816
+
817
+ expected.delete :id
818
+ assert_equal expected, default_route.recognize('/accounts/show')
819
+ assert_equal expected, default_route.recognize('/accounts/show/')
820
+
821
+ expected[:action] = 'index'
822
+ assert_equal expected, default_route.recognize('/accounts/')
823
+ assert_equal expected, default_route.recognize('/accounts')
824
+
825
+ assert_equal nil, default_route.recognize('/')
826
+ assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free')
827
+ end
828
+
829
+ def test_default_route_should_omit_default_action
830
+ o = {:controller => 'accounts', :action => 'index'}
831
+ assert_equal '/accounts', default_route.generate(o, o, {})
832
+ end
833
+
834
+ def test_default_route_should_include_default_action_when_id_present
835
+ o = {:controller => 'accounts', :action => 'index', :id => '20'}
836
+ assert_equal '/accounts/index/20', default_route.generate(o, o, {})
837
+ end
838
+
839
+ def test_default_route_should_work_with_action_but_no_id
840
+ o = {:controller => 'accounts', :action => 'list_all'}
841
+ assert_equal '/accounts/list_all', default_route.generate(o, o, {})
842
+ end
843
+
844
+ def test_parameter_shell
845
+ page_url = ROUTING::Route.new
846
+ page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/}
847
+ assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell)
848
+ end
849
+
850
+ def test_defaults
851
+ route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html"
852
+ assert_equal(
853
+ { :controller => "users", :action => "show", :format => "html" },
854
+ route.defaults)
855
+ end
856
+
857
+ def test_builder_complains_without_controller
858
+ assert_raises(ArgumentError) do
859
+ ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index"
860
+ end
861
+ end
862
+
863
+ def test_significant_keys_for_default_route
864
+ keys = default_route.significant_keys.sort_by {|k| k.to_s }
865
+ assert_equal [:action, :controller, :id], keys
866
+ end
867
+
868
+ def test_significant_keys
869
+ user_url = ROUTING::Route.new
870
+ user_url.segments << (s = ROUTING::StaticSegment.new)
871
+ s.value = '/'
872
+ s.raw = true
873
+
874
+ user_url.segments << (s = ROUTING::StaticSegment.new)
875
+ s.value = 'user'
876
+
877
+ user_url.segments << (s = ROUTING::StaticSegment.new)
878
+ s.value = '/'
879
+ s.raw = true
880
+ s.is_optional = true
881
+
882
+ user_url.segments << (s = ROUTING::DynamicSegment.new)
883
+ s.key = :user
884
+
885
+ user_url.segments << (s = ROUTING::StaticSegment.new)
886
+ s.value = '/'
887
+ s.raw = true
888
+ s.is_optional = true
889
+
890
+ user_url.requirements = {:controller => 'users', :action => 'show'}
891
+
892
+ keys = user_url.significant_keys.sort_by { |k| k.to_s }
893
+ assert_equal [:action, :controller, :user], keys
894
+ end
895
+
896
+ def test_build_empty_query_string
897
+ assert_equal '', @route.build_query_string({})
898
+ end
899
+
900
+ def test_build_query_string_with_nil_value
901
+ assert_equal '', @route.build_query_string({:x => nil})
902
+ end
903
+
904
+ def test_simple_build_query_string
905
+ assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2'))
906
+ end
907
+
908
+ def test_convert_ints_build_query_string
909
+ assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2))
910
+ end
911
+
912
+ def test_escape_spaces_build_query_string
913
+ assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world'))
914
+ end
915
+
916
+ def test_expand_array_build_query_string
917
+ assert_equal '?x[]=1&x[]=2', order_query_string(@route.build_query_string(:x => [1, 2]))
918
+ end
919
+
920
+ def test_escape_spaces_build_query_string_selected_keys
921
+ assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x]))
922
+ end
923
+
924
+ private
925
+ def order_query_string(qs)
926
+ '?' + qs[1..-1].split('&').sort.join('&')
927
+ end
928
+ end
929
+
930
+ class RouteBuilderTest < Test::Unit::TestCase
931
+
932
+ def builder
933
+ @builder ||= ROUTING::RouteBuilder.new
934
+ end
935
+
936
+ def build(path, options)
937
+ builder.build(path, options)
938
+ end
939
+
940
+ def test_options_should_not_be_modified
941
+ requirements1 = { :id => /\w+/, :controller => /(?:[a-z](?:-?[a-z]+)*)/ }
942
+ requirements2 = requirements1.dup
943
+
944
+ assert_equal requirements1, requirements2
945
+
946
+ with_options(:controller => 'folder',
947
+ :requirements => requirements2) do |m|
948
+ m.build 'folders/new', :action => 'new'
949
+ end
950
+
951
+ assert_equal requirements1, requirements2
952
+ end
953
+
954
+ def test_segment_for_static
955
+ segment, rest = builder.segment_for 'ulysses'
956
+ assert_equal '', rest
957
+ assert_kind_of ROUTING::StaticSegment, segment
958
+ assert_equal 'ulysses', segment.value
959
+ end
960
+
961
+ def test_segment_for_action
962
+ segment, rest = builder.segment_for ':action'
963
+ assert_equal '', rest
964
+ assert_kind_of ROUTING::DynamicSegment, segment
965
+ assert_equal :action, segment.key
966
+ assert_equal 'index', segment.default
967
+ end
968
+
969
+ def test_segment_for_dynamic
970
+ segment, rest = builder.segment_for ':login'
971
+ assert_equal '', rest
972
+ assert_kind_of ROUTING::DynamicSegment, segment
973
+ assert_equal :login, segment.key
974
+ assert_equal nil, segment.default
975
+ assert ! segment.optional?
976
+ end
977
+
978
+ def test_segment_for_with_rest
979
+ segment, rest = builder.segment_for ':login/:action'
980
+ assert_equal :login, segment.key
981
+ assert_equal '/:action', rest
982
+ segment, rest = builder.segment_for rest
983
+ assert_equal '/', segment.value
984
+ assert_equal ':action', rest
985
+ segment, rest = builder.segment_for rest
986
+ assert_equal :action, segment.key
987
+ assert_equal '', rest
988
+ end
989
+
990
+ def test_segments_for
991
+ segments = builder.segments_for_route_path '/:controller/:action/:id'
992
+
993
+ assert_kind_of ROUTING::DividerSegment, segments[0]
994
+ assert_equal '/', segments[2].value
995
+
996
+ assert_kind_of ROUTING::DynamicSegment, segments[1]
997
+ assert_equal :controller, segments[1].key
998
+
999
+ assert_kind_of ROUTING::DividerSegment, segments[2]
1000
+ assert_equal '/', segments[2].value
1001
+
1002
+ assert_kind_of ROUTING::DynamicSegment, segments[3]
1003
+ assert_equal :action, segments[3].key
1004
+
1005
+ assert_kind_of ROUTING::DividerSegment, segments[4]
1006
+ assert_equal '/', segments[4].value
1007
+
1008
+ assert_kind_of ROUTING::DynamicSegment, segments[5]
1009
+ assert_equal :id, segments[5].key
1010
+ end
1011
+
1012
+ def test_segment_for_action
1013
+ s, r = builder.segment_for(':action/something/else')
1014
+ assert_equal '/something/else', r
1015
+ assert_equal :action, s.key
1016
+ end
1017
+
1018
+ def test_action_default_should_not_trigger_on_prefix
1019
+ s, r = builder.segment_for ':action_name/something/else'
1020
+ assert_equal '/something/else', r
1021
+ assert_equal :action_name, s.key
1022
+ assert_equal nil, s.default
1023
+ end
1024
+
1025
+ def test_divide_route_options
1026
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1027
+ defaults, requirements = builder.divide_route_options(segments,
1028
+ :action => 'buy', :person => /\w+/, :car => /\w+/,
1029
+ :defaults => {:person => nil, :car => nil}
1030
+ )
1031
+
1032
+ assert_equal({:action => 'buy', :person => nil, :car => nil}, defaults)
1033
+ assert_equal({:person => /\w+/, :car => /\w+/}, requirements)
1034
+ end
1035
+
1036
+ def test_assign_route_options
1037
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1038
+ defaults = {:action => 'buy', :person => nil, :car => nil}
1039
+ requirements = {:person => /\w+/, :car => /\w+/}
1040
+
1041
+ route_requirements = builder.assign_route_options(segments, defaults, requirements)
1042
+ assert_equal({}, route_requirements)
1043
+
1044
+ assert_equal :action, segments[3].key
1045
+ assert_equal 'buy', segments[3].default
1046
+
1047
+ assert_equal :person, segments[5].key
1048
+ assert_equal %r/\w+/, segments[5].regexp
1049
+ assert segments[5].optional?
1050
+
1051
+ assert_equal :car, segments[7].key
1052
+ assert_equal %r/\w+/, segments[7].regexp
1053
+ assert segments[7].optional?
1054
+ end
1055
+
1056
+ def test_assign_route_options_with_anchor_chars
1057
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1058
+ defaults = {:action => 'buy', :person => nil, :car => nil}
1059
+ requirements = {:person => /\w+/, :car => /^\w+$/}
1060
+
1061
+ assert_raises ArgumentError do
1062
+ route_requirements = builder.assign_route_options(segments, defaults, requirements)
1063
+ end
1064
+
1065
+ requirements[:car] = /[^\/]+/
1066
+ route_requirements = builder.assign_route_options(segments, defaults, requirements)
1067
+ end
1068
+
1069
+
1070
+ def test_optional_segments_preceding_required_segments
1071
+ segments = builder.segments_for_route_path '/cars/:action/:person/:car/'
1072
+ defaults = {:action => 'buy', :person => nil, :car => "model-t"}
1073
+ assert builder.assign_route_options(segments, defaults, {}).empty?
1074
+
1075
+ 0.upto(1) { |i| assert !segments[i].optional?, "segment #{i} is optional and it shouldn't be" }
1076
+ assert segments[2].optional?
1077
+
1078
+ assert_equal nil, builder.warn_output # should only warn on the :person segment
1079
+ end
1080
+
1081
+ def test_segmentation_of_semicolon_path
1082
+ segments = builder.segments_for_route_path '/books/:id;:action'
1083
+ defaults = { :action => 'show' }
1084
+ assert builder.assign_route_options(segments, defaults, {}).empty?
1085
+ segments.each do |segment|
1086
+ assert ! segment.optional? || segment.key == :action
1087
+ end
1088
+ end
1089
+
1090
+ def test_segmentation_of_dot_path
1091
+ segments = builder.segments_for_route_path '/books/:action.rss'
1092
+ assert builder.assign_route_options(segments, {}, {}).empty?
1093
+ assert_equal 6, segments.length # "/", "books", "/", ":action", ".", "rss"
1094
+ assert !segments.any? { |seg| seg.optional? }
1095
+ end
1096
+
1097
+ def test_segmentation_of_dynamic_dot_path
1098
+ segments = builder.segments_for_route_path '/books/:action.:format'
1099
+ assert builder.assign_route_options(segments, {}, {}).empty?
1100
+ assert_equal 6, segments.length # "/", "books", "/", ":action", ".", ":format"
1101
+ assert !segments.any? { |seg| seg.optional? }
1102
+ assert_kind_of ROUTING::DynamicSegment, segments.last
1103
+ end
1104
+
1105
+ def test_assignment_of_default_options
1106
+ segments = builder.segments_for_route_path '/:controller/:action/:id/'
1107
+ action, id = segments[-4], segments[-2]
1108
+
1109
+ assert_equal :action, action.key
1110
+ assert_equal :id, id.key
1111
+ assert ! action.optional?
1112
+ assert ! id.optional?
1113
+
1114
+ builder.assign_default_route_options(segments)
1115
+
1116
+ assert_equal 'index', action.default
1117
+ assert action.optional?
1118
+ assert id.optional?
1119
+ end
1120
+
1121
+ def test_assignment_of_default_options_respects_existing_defaults
1122
+ segments = builder.segments_for_route_path '/:controller/:action/:id/'
1123
+ action, id = segments[-4], segments[-2]
1124
+
1125
+ assert_equal :action, action.key
1126
+ assert_equal :id, id.key
1127
+ action.default = 'show'
1128
+ action.is_optional = true
1129
+
1130
+ id.default = 'Welcome'
1131
+ id.is_optional = true
1132
+
1133
+ builder.assign_default_route_options(segments)
1134
+
1135
+ assert_equal 'show', action.default
1136
+ assert action.optional?
1137
+ assert_equal 'Welcome', id.default
1138
+ assert id.optional?
1139
+ end
1140
+
1141
+ def test_assignment_of_default_options_respects_regexps
1142
+ segments = builder.segments_for_route_path '/:controller/:action/:id/'
1143
+ action = segments[-4]
1144
+
1145
+ assert_equal :action, action.key
1146
+ action.regexp = /show|in/ # Use 'in' to check partial matches
1147
+
1148
+ builder.assign_default_route_options(segments)
1149
+
1150
+ assert_equal nil, action.default
1151
+ assert ! action.optional?
1152
+ end
1153
+
1154
+ def test_assignment_of_is_optional_when_default
1155
+ segments = builder.segments_for_route_path '/books/:action.rss'
1156
+ assert_equal segments[3].key, :action
1157
+ segments[3].default = 'changes'
1158
+ builder.ensure_required_segments(segments)
1159
+ assert ! segments[3].optional?
1160
+ end
1161
+
1162
+ def test_is_optional_is_assigned_to_default_segments
1163
+ segments = builder.segments_for_route_path '/books/:action'
1164
+ builder.assign_route_options(segments, {:action => 'index'}, {})
1165
+
1166
+ assert_equal segments[3].key, :action
1167
+ assert segments[3].optional?
1168
+ assert_kind_of ROUTING::DividerSegment, segments[2]
1169
+ assert segments[2].optional?
1170
+ end
1171
+
1172
+ # XXX is optional not being set right?
1173
+ # /blah/:defaulted_segment <-- is the second slash optional? it should be.
1174
+
1175
+ def test_route_build
1176
+ ActionController::Routing.with_controllers %w(users pages) do
1177
+ r = builder.build '/:controller/:action/:id/', :action => nil
1178
+
1179
+ [0, 2, 4].each do |i|
1180
+ assert_kind_of ROUTING::DividerSegment, r.segments[i]
1181
+ assert_equal '/', r.segments[i].value
1182
+ assert r.segments[i].optional? if i > 1
1183
+ end
1184
+
1185
+ assert_kind_of ROUTING::DynamicSegment, r.segments[1]
1186
+ assert_equal :controller, r.segments[1].key
1187
+ assert_equal nil, r.segments[1].default
1188
+
1189
+ assert_kind_of ROUTING::DynamicSegment, r.segments[3]
1190
+ assert_equal :action, r.segments[3].key
1191
+ assert_equal 'index', r.segments[3].default
1192
+
1193
+ assert_kind_of ROUTING::DynamicSegment, r.segments[5]
1194
+ assert_equal :id, r.segments[5].key
1195
+ assert r.segments[5].optional?
1196
+ end
1197
+ end
1198
+
1199
+ def test_slashes_are_implied
1200
+ routes = [
1201
+ builder.build('/:controller/:action/:id/', :action => nil),
1202
+ builder.build('/:controller/:action/:id', :action => nil),
1203
+ builder.build(':controller/:action/:id', :action => nil),
1204
+ builder.build('/:controller/:action/:id/', :action => nil)
1205
+ ]
1206
+ expected = routes.first.segments.length
1207
+ routes.each_with_index do |route, i|
1208
+ found = route.segments.length
1209
+ assert_equal expected, found, "Route #{i + 1} has #{found} segments, expected #{expected}"
1210
+ end
1211
+ end
1212
+
1213
+ end
1214
+
1215
+ class RouteSetTest < Test::Unit::TestCase
1216
+ class MockController
1217
+ attr_accessor :routes
1218
+
1219
+ def initialize(routes)
1220
+ self.routes = routes
1221
+ end
1222
+
1223
+ def url_for(options)
1224
+ only_path = options.delete(:only_path)
1225
+ path = routes.generate(options)
1226
+ only_path ? path : "http://named.route.test#{path}"
1227
+ end
1228
+ end
1229
+
1230
+ class MockRequest
1231
+ attr_accessor :path, :path_parameters, :host, :subdomains, :domain, :method
1232
+
1233
+ def initialize(values={})
1234
+ values.each { |key, value| send("#{key}=", value) }
1235
+ if values[:host]
1236
+ subdomain, self.domain = values[:host].split(/\./, 2)
1237
+ self.subdomains = [subdomain]
1238
+ end
1239
+ end
1240
+ end
1241
+
1242
+ def set
1243
+ @set ||= ROUTING::RouteSet.new
1244
+ end
1245
+
1246
+ def request
1247
+ @request ||= MockRequest.new(:host => "named.routes.test", :method => :get)
1248
+ end
1249
+
1250
+ def test_generate_extras
1251
+ set.draw { |m| m.connect ':controller/:action/:id' }
1252
+ path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1253
+ assert_equal "/foo/bar/15", path
1254
+ assert_equal %w(that this), extras.map(&:to_s).sort
1255
+ end
1256
+
1257
+ def test_extra_keys
1258
+ set.draw { |m| m.connect ':controller/:action/:id' }
1259
+ extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1260
+ assert_equal %w(that this), extras.map(&:to_s).sort
1261
+ end
1262
+
1263
+ def test_generate_extras_not_first
1264
+ set.draw do |map|
1265
+ map.connect ':controller/:action/:id.:format'
1266
+ map.connect ':controller/:action/:id'
1267
+ end
1268
+ path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1269
+ assert_equal "/foo/bar/15", path
1270
+ assert_equal %w(that this), extras.map(&:to_s).sort
1271
+ end
1272
+
1273
+ def test_generate_not_first
1274
+ set.draw do |map|
1275
+ map.connect ':controller/:action/:id.:format'
1276
+ map.connect ':controller/:action/:id'
1277
+ end
1278
+ assert_equal "/foo/bar/15?this=hello", set.generate(:controller => "foo", :action => "bar", :id => 15, :this => "hello")
1279
+ end
1280
+
1281
+ def test_extra_keys_not_first
1282
+ set.draw do |map|
1283
+ map.connect ':controller/:action/:id.:format'
1284
+ map.connect ':controller/:action/:id'
1285
+ end
1286
+ extras = set.extra_keys(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world")
1287
+ assert_equal %w(that this), extras.map(&:to_s).sort
1288
+ end
1289
+
1290
+ def test_draw
1291
+ assert_equal 0, set.routes.size
1292
+ set.draw do |map|
1293
+ map.connect '/hello/world', :controller => 'a', :action => 'b'
1294
+ end
1295
+ assert_equal 1, set.routes.size
1296
+ end
1297
+
1298
+ def test_named_draw
1299
+ assert_equal 0, set.routes.size
1300
+ set.draw do |map|
1301
+ map.hello '/hello/world', :controller => 'a', :action => 'b'
1302
+ end
1303
+ assert_equal 1, set.routes.size
1304
+ assert_equal set.routes.first, set.named_routes[:hello]
1305
+ end
1306
+
1307
+ def test_later_named_routes_take_precedence
1308
+ set.draw do |map|
1309
+ map.hello '/hello/world', :controller => 'a', :action => 'b'
1310
+ map.hello '/hello', :controller => 'a', :action => 'b'
1311
+ end
1312
+ assert_equal set.routes.last, set.named_routes[:hello]
1313
+ end
1314
+
1315
+ def setup_named_route_test
1316
+ set.draw do |map|
1317
+ map.show '/people/:id', :controller => 'people', :action => 'show'
1318
+ map.index '/people', :controller => 'people', :action => 'index'
1319
+ map.multi '/people/go/:foo/:bar/joe/:id', :controller => 'people', :action => 'multi'
1320
+ map.users '/admin/users', :controller => 'admin/users', :action => 'index'
1321
+ end
1322
+
1323
+ klass = Class.new(MockController)
1324
+ set.named_routes.install(klass)
1325
+ klass.new(set)
1326
+ end
1327
+
1328
+ def test_named_route_hash_access_method
1329
+ controller = setup_named_route_test
1330
+
1331
+ assert_equal(
1332
+ { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => false },
1333
+ controller.send(:hash_for_show_url, :id => 5))
1334
+
1335
+ assert_equal(
1336
+ { :controller => 'people', :action => 'index', :use_route => :index, :only_path => false },
1337
+ controller.send(:hash_for_index_url))
1338
+
1339
+ assert_equal(
1340
+ { :controller => 'people', :action => 'show', :id => 5, :use_route => :show, :only_path => true },
1341
+ controller.send(:hash_for_show_path, :id => 5)
1342
+ )
1343
+ end
1344
+
1345
+ def test_named_route_url_method
1346
+ controller = setup_named_route_test
1347
+
1348
+ assert_equal "http://named.route.test/people/5", controller.send(:show_url, :id => 5)
1349
+ assert_equal "/people/5", controller.send(:show_path, :id => 5)
1350
+
1351
+ assert_equal "http://named.route.test/people", controller.send(:index_url)
1352
+ assert_equal "/people", controller.send(:index_path)
1353
+
1354
+ assert_equal "http://named.route.test/admin/users", controller.send(:users_url)
1355
+ assert_equal '/admin/users', controller.send(:users_path)
1356
+ assert_equal '/admin/users', set.generate(controller.send(:hash_for_users_url), {:controller => 'users', :action => 'index'})
1357
+ end
1358
+
1359
+ def test_namd_route_url_method_with_ordered_parameters
1360
+ controller = setup_named_route_test
1361
+ assert_equal "http://named.route.test/people/go/7/hello/joe/5",
1362
+ controller.send(:multi_url, 7, "hello", 5)
1363
+ end
1364
+
1365
+ def test_draw_default_route
1366
+ ActionController::Routing.with_controllers(['users']) do
1367
+ set.draw do |map|
1368
+ map.connect '/:controller/:action/:id'
1369
+ end
1370
+
1371
+ assert_equal 1, set.routes.size
1372
+ route = set.routes.first
1373
+
1374
+ assert route.segments.last.optional?
1375
+
1376
+ assert_equal '/users/show/10', set.generate(:controller => 'users', :action => 'show', :id => 10)
1377
+ assert_equal '/users/index/10', set.generate(:controller => 'users', :id => 10)
1378
+
1379
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10'))
1380
+ assert_equal({:controller => 'users', :action => 'index', :id => '10'}, set.recognize_path('/users/index/10/'))
1381
+ end
1382
+ end
1383
+
1384
+ def test_draw_default_route_with_default_controller
1385
+ ActionController::Routing.with_controllers(['users']) do
1386
+ set.draw do |map|
1387
+ map.connect '/:controller/:action/:id', :controller => 'users'
1388
+ end
1389
+ assert_equal({:controller => 'users', :action => 'index'}, set.recognize_path('/'))
1390
+ end
1391
+ end
1392
+
1393
+ def test_route_with_parameter_shell
1394
+ ActionController::Routing.with_controllers(['users', 'pages']) do
1395
+ set.draw do |map|
1396
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
1397
+ map.connect '/:controller/:action/:id'
1398
+ end
1399
+
1400
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages'))
1401
+ assert_equal({:controller => 'pages', :action => 'index'}, set.recognize_path('/pages/index'))
1402
+ assert_equal({:controller => 'pages', :action => 'list'}, set.recognize_path('/pages/list'))
1403
+
1404
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/pages/show/10'))
1405
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
1406
+ end
1407
+ end
1408
+
1409
+ def test_route_requirements_with_anchor_chars_are_invalid
1410
+ assert_raises ArgumentError do
1411
+ set.draw do |map|
1412
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /^\d+/
1413
+ end
1414
+ end
1415
+ assert_raises ArgumentError do
1416
+ set.draw do |map|
1417
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\A\d+/
1418
+ end
1419
+ end
1420
+ assert_raises ArgumentError do
1421
+ set.draw do |map|
1422
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+$/
1423
+ end
1424
+ end
1425
+ assert_raises ArgumentError do
1426
+ set.draw do |map|
1427
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\Z/
1428
+ end
1429
+ end
1430
+ assert_raises ArgumentError do
1431
+ set.draw do |map|
1432
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+\z/
1433
+ end
1434
+ end
1435
+ assert_nothing_raised do
1436
+ set.draw do |map|
1437
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /\d+/, :name => /^(david|jamis)/
1438
+ end
1439
+ assert_raises ActionController::RoutingError do
1440
+ set.generate :controller => 'pages', :action => 'show', :id => 10
1441
+ end
1442
+ end
1443
+ end
1444
+
1445
+ def test_non_path_route_requirements_match_all
1446
+ set.draw do |map|
1447
+ map.connect 'page/37s', :controller => 'pages', :action => 'show', :name => /(jamis|david)/
1448
+ end
1449
+ assert_equal '/page/37s', set.generate(:controller => 'pages', :action => 'show', :name => 'jamis')
1450
+ assert_raises ActionController::RoutingError do
1451
+ set.generate(:controller => 'pages', :action => 'show', :name => 'not_jamis')
1452
+ end
1453
+ assert_raises ActionController::RoutingError do
1454
+ set.generate(:controller => 'pages', :action => 'show', :name => 'nor_jamis_and_david')
1455
+ end
1456
+ end
1457
+
1458
+ def test_recognize_with_encoded_id_and_regex
1459
+ set.draw do |map|
1460
+ map.connect 'page/:id', :controller => 'pages', :action => 'show', :id => /[a-zA-Z0-9 ]+/
1461
+ end
1462
+
1463
+ assert_equal({:controller => 'pages', :action => 'show', :id => '10'}, set.recognize_path('/page/10'))
1464
+ assert_equal({:controller => 'pages', :action => 'show', :id => 'hello world'}, set.recognize_path('/page/hello+world'))
1465
+ end
1466
+
1467
+ def test_recognize_with_conditions
1468
+ Object.const_set(:PeopleController, Class.new)
1469
+
1470
+ set.draw do |map|
1471
+ map.with_options(:controller => "people") do |people|
1472
+ people.people "/people", :action => "index", :conditions => { :method => :get }
1473
+ people.connect "/people", :action => "create", :conditions => { :method => :post }
1474
+ people.person "/people/:id", :action => "show", :conditions => { :method => :get }
1475
+ people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
1476
+ people.connect "/people/:id", :action => "destroy", :conditions => { :method => :delete }
1477
+ end
1478
+ end
1479
+
1480
+ request.path = "/people"
1481
+ request.method = :get
1482
+ assert_nothing_raised { set.recognize(request) }
1483
+ assert_equal("index", request.path_parameters[:action])
1484
+
1485
+ request.method = :post
1486
+ assert_nothing_raised { set.recognize(request) }
1487
+ assert_equal("create", request.path_parameters[:action])
1488
+
1489
+ request.method = :put
1490
+ assert_nothing_raised { set.recognize(request) }
1491
+ assert_equal("update", request.path_parameters[:action])
1492
+
1493
+ request.method = :update
1494
+ assert_raises(ActionController::RoutingError) { set.recognize(request) }
1495
+
1496
+ request.path = "/people/5"
1497
+ request.method = :get
1498
+ assert_nothing_raised { set.recognize(request) }
1499
+ assert_equal("show", request.path_parameters[:action])
1500
+ assert_equal("5", request.path_parameters[:id])
1501
+
1502
+ request.method = :put
1503
+ assert_nothing_raised { set.recognize(request) }
1504
+ assert_equal("update", request.path_parameters[:action])
1505
+ assert_equal("5", request.path_parameters[:id])
1506
+
1507
+ request.method = :delete
1508
+ assert_nothing_raised { set.recognize(request) }
1509
+ assert_equal("destroy", request.path_parameters[:action])
1510
+ assert_equal("5", request.path_parameters[:id])
1511
+
1512
+ request.method = :post
1513
+ assert_raises(ActionController::RoutingError) { set.recognize(request) }
1514
+
1515
+ ensure
1516
+ Object.send(:remove_const, :PeopleController)
1517
+ end
1518
+
1519
+ def test_typo_recognition
1520
+ Object.const_set(:ArticlesController, Class.new)
1521
+
1522
+ set.draw do |map|
1523
+ map.connect 'articles/:year/:month/:day/:title',
1524
+ :controller => 'articles', :action => 'permalink',
1525
+ :year => /\d{4}/, :day => /\d{1,2}/, :month => /\d{1,2}/
1526
+ end
1527
+
1528
+ request.path = "/articles/2005/11/05/a-very-interesting-article"
1529
+ request.method = :get
1530
+ assert_nothing_raised { set.recognize(request) }
1531
+ assert_equal("permalink", request.path_parameters[:action])
1532
+ assert_equal("2005", request.path_parameters[:year])
1533
+ assert_equal("11", request.path_parameters[:month])
1534
+ assert_equal("05", request.path_parameters[:day])
1535
+ assert_equal("a-very-interesting-article", request.path_parameters[:title])
1536
+
1537
+ ensure
1538
+ Object.send(:remove_const, :ArticlesController)
1539
+ end
1540
+
1541
+ def test_routing_traversal_does_not_load_extra_classes
1542
+ assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
1543
+ set.draw do |map|
1544
+ map.connect '/profile', :controller => 'profile'
1545
+ end
1546
+
1547
+ request.path = '/profile'
1548
+
1549
+ set.recognize(request) rescue nil
1550
+
1551
+ assert !Object.const_defined?("Profiler__"), "Profiler should not be loaded"
1552
+ end
1553
+
1554
+ def test_recognize_with_conditions_and_format
1555
+ Object.const_set(:PeopleController, Class.new)
1556
+
1557
+ set.draw do |map|
1558
+ map.with_options(:controller => "people") do |people|
1559
+ people.person "/people/:id", :action => "show", :conditions => { :method => :get }
1560
+ people.connect "/people/:id", :action => "update", :conditions => { :method => :put }
1561
+ people.connect "/people/:id.:_format", :action => "show", :conditions => { :method => :get }
1562
+ end
1563
+ end
1564
+
1565
+ request.path = "/people/5"
1566
+ request.method = :get
1567
+ assert_nothing_raised { set.recognize(request) }
1568
+ assert_equal("show", request.path_parameters[:action])
1569
+ assert_equal("5", request.path_parameters[:id])
1570
+
1571
+ request.method = :put
1572
+ assert_nothing_raised { set.recognize(request) }
1573
+ assert_equal("update", request.path_parameters[:action])
1574
+
1575
+ request.path = "/people/5.png"
1576
+ request.method = :get
1577
+ assert_nothing_raised { set.recognize(request) }
1578
+ assert_equal("show", request.path_parameters[:action])
1579
+ assert_equal("5", request.path_parameters[:id])
1580
+ assert_equal("png", request.path_parameters[:_format])
1581
+ ensure
1582
+ Object.send(:remove_const, :PeopleController)
1583
+ end
1584
+
1585
+ def test_deprecation_warning_for_root_route
1586
+ Object.const_set(:PeopleController, Class.new)
1587
+
1588
+ set.draw do |map|
1589
+ assert_deprecated do
1590
+ map.root('', :controller => "people")
1591
+ end
1592
+ end
1593
+ ensure
1594
+ Object.send(:remove_const, :PeopleController)
1595
+ end
1596
+
1597
+ def test_generate_with_default_action
1598
+ set.draw do |map|
1599
+ map.connect "/people", :controller => "people"
1600
+ map.connect "/people/list", :controller => "people", :action => "list"
1601
+ end
1602
+
1603
+ url = set.generate(:controller => "people", :action => "list")
1604
+ assert_equal "/people/list", url
1605
+ end
1606
+
1607
+ def test_generate_finds_best_fit
1608
+ set.draw do |map|
1609
+ map.connect "/people", :controller => "people", :action => "index"
1610
+ map.connect "/ws/people", :controller => "people", :action => "index", :ws => true
1611
+ end
1612
+
1613
+ url = set.generate(:controller => "people", :action => "index", :ws => true)
1614
+ assert_equal "/ws/people", url
1615
+ end
1616
+
1617
+ def test_generate_changes_controller_module
1618
+ set.draw { |map| map.connect ':controller/:action/:id' }
1619
+ current = { :controller => "bling/bloop", :action => "bap", :id => 9 }
1620
+ url = set.generate({:controller => "foo/bar", :action => "baz", :id => 7}, current)
1621
+ assert_equal "/foo/bar/baz/7", url
1622
+ end
1623
+
1624
+ def test_id_is_not_impossibly_sticky
1625
+ set.draw do |map|
1626
+ map.connect 'foo/:number', :controller => "people", :action => "index"
1627
+ map.connect ':controller/:action/:id'
1628
+ end
1629
+
1630
+ url = set.generate({:controller => "people", :action => "index", :number => 3},
1631
+ {:controller => "people", :action => "index", :id => "21"})
1632
+ assert_equal "/foo/3", url
1633
+ end
1634
+
1635
+ def test_id_is_sticky_when_it_ought_to_be
1636
+ set.draw do |map|
1637
+ map.connect ':controller/:id/:action'
1638
+ end
1639
+
1640
+ url = set.generate({:action => "destroy"}, {:controller => "people", :action => "show", :id => "7"})
1641
+ assert_equal "/people/7/destroy", url
1642
+ end
1643
+
1644
+ def test_use_static_path_when_possible
1645
+ set.draw do |map|
1646
+ map.connect 'about', :controller => "welcome", :action => "about"
1647
+ map.connect ':controller/:action/:id'
1648
+ end
1649
+
1650
+ url = set.generate({:controller => "welcome", :action => "about"},
1651
+ {:controller => "welcome", :action => "get", :id => "7"})
1652
+ assert_equal "/about", url
1653
+ end
1654
+
1655
+ def test_generate
1656
+ set.draw { |map| map.connect ':controller/:action/:id' }
1657
+
1658
+ args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
1659
+ assert_equal "/foo/bar/7?x=y", set.generate(args)
1660
+ assert_equal ["/foo/bar/7", [:x]], set.generate_extras(args)
1661
+ assert_equal [:x], set.extra_keys(args)
1662
+ end
1663
+
1664
+ def test_named_routes_are_never_relative_to_modules
1665
+ set.draw do |map|
1666
+ map.connect "/connection/manage/:action", :controller => 'connection/manage'
1667
+ map.connect "/connection/connection", :controller => "connection/connection"
1668
+ map.family_connection "/connection", :controller => "connection"
1669
+ end
1670
+
1671
+ url = set.generate({:controller => "connection"}, {:controller => 'connection/manage'})
1672
+ assert_equal "/connection/connection", url
1673
+
1674
+ url = set.generate({:use_route => :family_connection, :controller => "connection"}, {:controller => 'connection/manage'})
1675
+ assert_equal "/connection", url
1676
+ end
1677
+
1678
+ def test_action_left_off_when_id_is_recalled
1679
+ set.draw do |map|
1680
+ map.connect ':controller/:action/:id'
1681
+ end
1682
+ assert_equal '/post', set.generate(
1683
+ {:controller => 'post', :action => 'index'},
1684
+ {:controller => 'post', :action => 'show', :id => '10'}
1685
+ )
1686
+ end
1687
+
1688
+ end
1689
+
1690
+ class RoutingTest < Test::Unit::TestCase
1691
+
1692
+ def test_possible_controllers
1693
+ true_controller_paths = ActionController::Routing.controller_paths
1694
+
1695
+ ActionController::Routing.use_controllers! nil
1696
+
1697
+ silence_warnings do
1698
+ Object.send(:const_set, :RAILS_ROOT, File.dirname(__FILE__) + '/controller_fixtures')
1699
+ end
1700
+
1701
+ ActionController::Routing.controller_paths = [
1702
+ RAILS_ROOT, RAILS_ROOT + '/app/controllers', RAILS_ROOT + '/vendor/plugins/bad_plugin/lib'
1703
+ ]
1704
+
1705
+ assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
1706
+ ensure
1707
+ if true_controller_paths
1708
+ ActionController::Routing.controller_paths = true_controller_paths
1709
+ end
1710
+ ActionController::Routing.use_controllers! nil
1711
+ Object.send(:remove_const, :RAILS_ROOT) rescue nil
1712
+ end
1713
+
1714
+ def test_possible_controllers_are_reset_on_each_load
1715
+ true_possible_controllers = ActionController::Routing.possible_controllers
1716
+ true_controller_paths = ActionController::Routing.controller_paths
1717
+
1718
+ ActionController::Routing.use_controllers! nil
1719
+ root = File.dirname(__FILE__) + '/controller_fixtures'
1720
+
1721
+ ActionController::Routing.controller_paths = []
1722
+ assert_equal [], ActionController::Routing.possible_controllers
1723
+
1724
+ ActionController::Routing::Routes.load!
1725
+ ActionController::Routing.controller_paths = [
1726
+ root, root + '/app/controllers', root + '/vendor/plugins/bad_plugin/lib'
1727
+ ]
1728
+
1729
+ assert_equal ["admin/user", "plugin", "user"], ActionController::Routing.possible_controllers.sort
1730
+ ensure
1731
+ ActionController::Routing.controller_paths = true_controller_paths
1732
+ ActionController::Routing.use_controllers! true_possible_controllers
1733
+ Object.send(:remove_const, :RAILS_ROOT) rescue nil
1734
+
1735
+ ActionController::Routing::Routes.clear!
1736
+ ActionController::Routing::Routes.load_routes!
1737
+ end
1738
+
1739
+ def test_with_controllers
1740
+ c = %w(admin/accounts admin/users account pages)
1741
+ ActionController::Routing.with_controllers c do
1742
+ assert_equal c, ActionController::Routing.possible_controllers
1743
+ end
1744
+ end
1745
+
1746
+ def test_normalize_unix_paths
1747
+ 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)
1748
+ paths = ActionController::Routing.normalize_paths(load_paths)
1749
+ assert_equal %w(vendor/rails/railties/builtin/rails_info vendor/rails/actionpack/lib app/controllers app/helpers app/models lib .), paths
1750
+ end
1751
+
1752
+ def test_normalize_windows_paths
1753
+ 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)
1754
+ paths = ActionController::Routing.normalize_paths(load_paths)
1755
+ assert_equal %w(vendor\\rails\\railties\\builtin\\rails_info vendor\\rails\\actionpack\\lib app\\controllers app\\helpers app\\models lib .), paths
1756
+ end
1757
+
1049
1758
  end