~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/actionpack/test/controller/routing_test.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

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