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.
- data/CHANGELOG +517 -15
- data/MIT-LICENSE +1 -1
- data/README +18 -20
- data/Rakefile +7 -4
- data/examples/address_book_controller.rb +3 -3
- data/examples/blog_controller.cgi +3 -3
- data/examples/debate_controller.cgi +5 -5
- data/lib/action_controller.rb +2 -2
- data/lib/action_controller/assertions.rb +73 -311
- data/lib/action_controller/{deprecated_assertions.rb → assertions/deprecated_assertions.rb} +32 -8
- data/lib/action_controller/assertions/dom_assertions.rb +25 -0
- data/lib/action_controller/assertions/model_assertions.rb +12 -0
- data/lib/action_controller/assertions/response_assertions.rb +140 -0
- data/lib/action_controller/assertions/routing_assertions.rb +82 -0
- data/lib/action_controller/assertions/selector_assertions.rb +571 -0
- data/lib/action_controller/assertions/tag_assertions.rb +117 -0
- data/lib/action_controller/base.rb +334 -163
- data/lib/action_controller/benchmarking.rb +3 -6
- data/lib/action_controller/caching.rb +83 -22
- data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -7
- data/lib/action_controller/cgi_ext/cgi_methods.rb +167 -173
- data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +43 -22
- data/lib/action_controller/cgi_process.rb +50 -27
- data/lib/action_controller/components.rb +21 -25
- data/lib/action_controller/cookies.rb +10 -9
- data/lib/action_controller/{dependencies.rb → deprecated_dependencies.rb} +9 -27
- data/lib/action_controller/filters.rb +448 -225
- data/lib/action_controller/flash.rb +24 -20
- data/lib/action_controller/helpers.rb +2 -5
- data/lib/action_controller/integration.rb +40 -16
- data/lib/action_controller/layout.rb +11 -8
- data/lib/action_controller/macros/auto_complete.rb +3 -2
- data/lib/action_controller/macros/in_place_editing.rb +3 -2
- data/lib/action_controller/mime_responds.rb +41 -29
- data/lib/action_controller/mime_type.rb +68 -10
- data/lib/action_controller/pagination.rb +4 -3
- data/lib/action_controller/request.rb +22 -14
- data/lib/action_controller/rescue.rb +25 -22
- data/lib/action_controller/resources.rb +302 -0
- data/lib/action_controller/response.rb +20 -2
- data/lib/action_controller/response.rb.rej +17 -0
- data/lib/action_controller/routing.rb +1165 -567
- data/lib/action_controller/scaffolding.rb +30 -31
- data/lib/action_controller/session/active_record_store.rb +2 -0
- data/lib/action_controller/session/drb_store.rb +4 -0
- data/lib/action_controller/session/mem_cache_store.rb +4 -0
- data/lib/action_controller/session_management.rb +6 -9
- data/lib/action_controller/status_codes.rb +89 -0
- data/lib/action_controller/streaming.rb +6 -15
- data/lib/action_controller/templates/rescues/_request_and_response.rhtml +5 -5
- data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -2
- data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -4
- data/lib/action_controller/templates/rescues/template_error.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +52 -30
- data/lib/action_controller/url_rewriter.rb +63 -29
- data/lib/action_controller/vendor/html-scanner/html/document.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +3 -4
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +822 -0
- data/lib/action_controller/verification.rb +22 -11
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +46 -43
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +54 -17
- data/lib/action_view/helpers/asset_tag_helper.rb +97 -46
- data/lib/action_view/helpers/capture_helper.rb +1 -1
- data/lib/action_view/helpers/date_helper.rb +258 -136
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/deprecated_helper.rb +34 -0
- data/lib/action_view/helpers/form_helper.rb +75 -35
- data/lib/action_view/helpers/form_options_helper.rb +7 -5
- data/lib/action_view/helpers/form_tag_helper.rb +44 -6
- data/lib/action_view/helpers/java_script_macros_helper.rb +59 -46
- data/lib/action_view/helpers/javascript_helper.rb +71 -10
- data/lib/action_view/helpers/javascripts/controls.js +41 -23
- data/lib/action_view/helpers/javascripts/dragdrop.js +105 -76
- data/lib/action_view/helpers/javascripts/effects.js +293 -163
- data/lib/action_view/helpers/javascripts/prototype.js +897 -389
- data/lib/action_view/helpers/javascripts/prototype.js.rej +561 -0
- data/lib/action_view/helpers/number_helper.rb +111 -65
- data/lib/action_view/helpers/prototype_helper.rb +84 -109
- data/lib/action_view/helpers/scriptaculous_helper.rb +5 -0
- data/lib/action_view/helpers/tag_helper.rb +69 -16
- data/lib/action_view/helpers/text_helper.rb +149 -112
- data/lib/action_view/helpers/url_helper.rb +200 -107
- data/lib/action_view/template_error.rb +66 -42
- data/test/abstract_unit.rb +4 -2
- data/test/active_record_unit.rb +84 -56
- data/test/activerecord/active_record_assertions_test.rb +26 -18
- data/test/activerecord/active_record_store_test.rb +4 -36
- data/test/activerecord/pagination_test.rb +1 -6
- data/test/controller/action_pack_assertions_test.rb +230 -113
- data/test/controller/addresses_render_test.rb +2 -6
- data/test/controller/assert_select_test.rb +576 -0
- data/test/controller/base_test.rb +73 -3
- data/test/controller/caching_test.rb +228 -0
- data/test/controller/capture_test.rb +12 -10
- data/test/controller/cgi_test.rb +89 -12
- data/test/controller/components_test.rb +24 -2
- data/test/controller/content_type_test.rb +139 -0
- data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
- data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
- data/test/controller/cookie_test.rb +33 -25
- data/test/controller/deprecated_instance_variables_test.rb +48 -0
- data/test/controller/deprecation/deprecated_base_methods_test.rb +60 -0
- data/test/controller/fake_controllers.rb +0 -1
- data/test/controller/filters_test.rb +301 -16
- data/test/controller/flash_test.rb +19 -2
- data/test/controller/helper_test.rb +2 -2
- data/test/controller/integration_test.rb +154 -0
- data/test/controller/layout_test.rb +115 -1
- data/test/controller/mime_responds_test.rb +94 -0
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/new_render_test.rb +161 -11
- data/test/controller/raw_post_test.rb +52 -15
- data/test/controller/redirect_test.rb +27 -14
- data/test/controller/render_test.rb +76 -29
- data/test/controller/request_test.rb +55 -4
- data/test/controller/resources_test.rb +274 -0
- data/test/controller/routing_test.rb +1533 -824
- data/test/controller/selector_test.rb +628 -0
- data/test/controller/send_file_test.rb +9 -1
- data/test/controller/session_management_test.rb +51 -0
- data/test/controller/test_test.rb +113 -29
- data/test/controller/url_rewriter_test.rb +86 -17
- data/test/controller/verification_test.rb +19 -17
- data/test/controller/webservice_test.rb +0 -7
- data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
- data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
- data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +1 -0
- data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +1 -0
- data/test/fixtures/multipart/binary_file +0 -0
- data/test/fixtures/public/javascripts/application.js +1 -0
- data/test/fixtures/test/_hello.rxml +1 -0
- data/test/fixtures/test/hello_world_container.rxml +3 -0
- data/test/fixtures/topic.rb +2 -2
- data/test/template/active_record_helper_test.rb +83 -12
- data/test/template/asset_tag_helper_test.rb +75 -95
- data/test/template/compiled_templates_test.rb +1 -0
- data/test/template/date_helper_test.rb +873 -181
- data/test/template/deprecated_helper_test.rb +36 -0
- data/test/template/deprecated_instance_variables_test.rb +43 -0
- data/test/template/form_helper_test.rb +77 -1
- data/test/template/form_options_helper_test.rb +4 -0
- data/test/template/form_tag_helper_test.rb +66 -2
- data/test/template/java_script_macros_helper_test.rb +4 -1
- data/test/template/javascript_helper_test.rb +29 -0
- data/test/template/number_helper_test.rb +63 -27
- data/test/template/prototype_helper_test.rb +77 -34
- data/test/template/tag_helper_test.rb +34 -6
- data/test/template/text_helper_test.rb +69 -34
- data/test/template/url_helper_test.rb +168 -16
- data/test/testing_sandbox.rb +7 -22
- metadata +66 -20
- data/filler.txt +0 -50
- data/lib/action_controller/code_generation.rb +0 -235
- data/lib/action_controller/vendor/xml_simple.rb +0 -1019
- data/test/controller/caching_filestore.rb +0 -74
- data/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb +0 -7
- data/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb +0 -3
- data/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb +0 -7
- 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 '
|
4
|
+
require 'action_controller/routing'
|
5
5
|
|
6
6
|
RunTimeTests = ARGV.include? 'time'
|
7
|
+
ROUTING = ActionController::Routing
|
7
8
|
|
8
|
-
|
9
|
+
class ROUTING::RouteBuilder
|
10
|
+
attr_reader :warn_output
|
9
11
|
|
10
|
-
|
11
|
-
|
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
|
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
|
-
|
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 =>
|
632
|
-
assert_equal({:controller =>
|
633
|
-
assert_equal({:controller =>
|
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 =>
|
30
|
+
assert_equal({:controller => "admin/user", :action => 'show', :id => '10'}, rs.recognize_path("/admin/user/show/10"))
|
636
31
|
|
637
|
-
assert_equal
|
32
|
+
assert_equal '/admin/user/show/10', rs.generate(:controller => 'admin/user', :action => 'show', :id => 10)
|
638
33
|
|
639
|
-
assert_equal
|
640
|
-
assert_equal
|
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
|
643
|
-
assert_equal
|
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(
|
658
|
-
rs.recognize_path(
|
659
|
-
rs.recognize_path(
|
660
|
-
rs.recognize_path(
|
661
|
-
rs.recognize_path(
|
662
|
-
rs.recognize_path(
|
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
|
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 '
|
103
|
+
map.connect ':controller/:admintoken/:action/:id', :controller => /admin\/.+/
|
104
|
+
map.connect ':controller/:action/:id'
|
711
105
|
end
|
712
|
-
assert_equal "",
|
713
|
-
|
714
|
-
|
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
|
113
|
+
def test_route_with_regexp_and_dot
|
718
114
|
rs.draw do |map|
|
719
|
-
map.connect ':controller/:
|
720
|
-
|
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
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
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 => '
|
734
|
-
x.
|
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 => '
|
741
|
-
x.
|
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 => '
|
748
|
-
x.
|
749
|
-
assert_equal({:controller => '
|
750
|
-
x.
|
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
|
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
|
-
|
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
|
-
|
770
|
-
:year =>
|
771
|
-
|
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 => '
|
776
|
-
x.
|
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 => '
|
780
|
-
x.
|
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
|
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
|
-
|
794
|
-
|
207
|
+
map.path 'file/*path', :controller => 'content', :action => 'show_file'
|
208
|
+
map.connect ':controller/:action/:id'
|
795
209
|
end
|
796
|
-
results = rs.recognize_path
|
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[
|
212
|
+
assert_equal ['hello world', 'how are you?'], results[:path]
|
799
213
|
|
800
|
-
results = rs.recognize_path
|
214
|
+
results = rs.recognize_path "/file"
|
801
215
|
assert results, "Recognition should have succeeded"
|
802
|
-
assert_equal [], results[
|
216
|
+
assert_equal [], results[:path]
|
803
217
|
end
|
804
218
|
|
805
219
|
def test_non_controllers_cannot_be_matched
|
806
|
-
rs.draw do
|
807
|
-
|
220
|
+
rs.draw do |map|
|
221
|
+
map.connect ':controller/:action/:id'
|
808
222
|
end
|
809
|
-
|
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
|
-
|
816
|
-
|
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
|
-
|
822
|
-
|
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
|
-
|
829
|
-
|
259
|
+
map.connect 'page/:id/:action', :controller => 'pages', :action => 'show'
|
260
|
+
map.connect ':controller/:action/:id'
|
830
261
|
end
|
831
262
|
|
832
|
-
assert_equal
|
833
|
-
assert_equal
|
834
|
-
assert_equal
|
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
|
-
|
840
|
-
|
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
|
844
|
-
assert_equal
|
845
|
-
assert_equal
|
846
|
-
assert_equal
|
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({
|
851
|
-
assert_equal({
|
852
|
-
assert_equal({
|
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
|
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({
|
861
|
-
assert_equal({
|
862
|
-
assert_equal({
|
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
|
-
|
865
|
-
assert_equal({'controller' =>
|
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
|
-
|
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
|
-
|
333
|
+
map.connect ':controller/:action/:id'
|
875
334
|
end
|
876
335
|
|
877
|
-
assert_equal
|
878
|
-
assert_equal
|
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 => '
|
882
|
-
x.
|
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
|
-
|
888
|
-
|
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
|
350
|
+
assert_equal '/pages/2005',
|
892
351
|
rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005)
|
893
|
-
assert_equal
|
352
|
+
assert_equal '/pages/2005/6',
|
894
353
|
rs.generate(:controller => 'content', :action => 'list_pages', :year => 2005, :month => 6)
|
895
|
-
assert_equal
|
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
|
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
|
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
|
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
|
-
|
911
|
-
|
368
|
+
rs.draw do |map|
|
369
|
+
map.connect '', :controller => 'content'
|
370
|
+
map.connect ':controller/:action/:id'
|
912
371
|
end
|
913
372
|
|
914
|
-
assert_equal
|
915
|
-
assert_equal
|
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
|
-
|
921
|
-
|
378
|
+
rs.draw do |map|
|
379
|
+
map.home '', :controller => 'content'
|
380
|
+
map.connect ':controller/:action/:id'
|
922
381
|
end
|
923
382
|
|
924
|
-
assert_equal
|
925
|
-
assert_equal
|
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 => '
|
929
|
-
x.
|
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
|
-
|
936
|
-
|
393
|
+
rs.draw do |map|
|
394
|
+
map.home '', hash
|
395
|
+
map.connect ':controller/:action/:id'
|
937
396
|
end
|
938
|
-
assert_equal
|
939
|
-
assert_equal
|
940
|
-
assert_equal
|
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
|
-
|
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
|
953
|
-
assert_equal
|
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
|
413
|
+
def test_named_routes_array
|
957
414
|
test_named_route_method
|
958
|
-
assert_equal [:
|
415
|
+
assert_equal [:categories], rs.named_routes.names
|
959
416
|
end
|
960
417
|
|
961
418
|
def test_nil_defaults
|
962
|
-
rs.draw do
|
963
|
-
|
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
|
-
|
424
|
+
map.connect ':controller/:action/:id'
|
968
425
|
end
|
969
426
|
|
970
|
-
assert_equal
|
427
|
+
assert_equal '/journal', rs.generate(:controller => 'content', :action => 'list_journal', :date => nil, :user_id => nil)
|
971
428
|
end
|
972
|
-
end
|
973
429
|
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
end
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
assert_equal
|
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
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
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
|
-
|
1044
|
-
|
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
|