diff options
| author | Joshua Peek <josh@joshpeek.com> | 2009-08-14 16:16:29 -0500 | 
|---|---|---|
| committer | Joshua Peek <josh@joshpeek.com> | 2009-08-14 16:16:29 -0500 | 
| commit | 940a391c9b0aaefa8d1e836332bd46ed74e7a9f4 (patch) | |
| tree | 24b5f6fe57084383268bae55e99d9eac5e391284 | |
| parent | f86a4b84ddded3fe29184196e4fdd7ffaa4c27ac (diff) | |
| download | rails-940a391c9b0aaefa8d1e836332bd46ed74e7a9f4.tar.gz rails-940a391c9b0aaefa8d1e836332bd46ed74e7a9f4.tar.bz2 rails-940a391c9b0aaefa8d1e836332bd46ed74e7a9f4.zip | |
Attempt to rewrite most of the highly coupled router segments tests
| -rw-r--r-- | actionpack/test/controller/routing_test.rb | 962 | 
1 files changed, 221 insertions, 741 deletions
| diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 398e22fd81..000f35e0f2 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -59,590 +59,6 @@ class UriReservedCharactersRoutingTest < Test::Unit::TestCase    end  end -class SegmentTest < Test::Unit::TestCase -  def test_first_segment_should_interpolate_for_structure -    s = ROUTING::Segment.new -    def s.interpolation_statement(array) 'hello' end -    assert_equal 'hello', s.continue_string_structure([]) -  end - -  def test_interpolation_statement -    s = ROUTING::StaticSegment.new("Hello") -    assert_equal "Hello", eval(s.interpolation_statement([])) -    assert_equal "HelloHello", eval(s.interpolation_statement([s])) - -    s2 = ROUTING::StaticSegment.new("-") -    assert_equal "Hello-Hello", eval(s.interpolation_statement([s, s2])) - -    s3 = ROUTING::StaticSegment.new("World") -    assert_equal "Hello-World", eval(s3.interpolation_statement([s, s2])) -  end -end - -class StaticSegmentTest < Test::Unit::TestCase -  def test_interpolation_chunk_should_respect_raw -    s = ROUTING::StaticSegment.new('Hello World') -    assert !s.raw? -    assert_equal 'Hello%20World', s.interpolation_chunk - -    s = ROUTING::StaticSegment.new('Hello World', :raw => true) -    assert s.raw? -    assert_equal 'Hello World', s.interpolation_chunk -  end - -  def test_value_should_not_be_double_unescaped -    s = ROUTING::StaticSegment.new('%D0%9A%D0%B0%D1%80%D1%82%D0%B0') # Карта -    assert_equal '%D0%9A%D0%B0%D1%80%D1%82%D0%B0', s.interpolation_chunk -  end - -  def test_regexp_chunk_should_escape_specials -    s = ROUTING::StaticSegment.new('Hello*World') -    assert_equal 'Hello\*World', s.regexp_chunk - -    s = ROUTING::StaticSegment.new('HelloWorld') -    assert_equal 'HelloWorld', s.regexp_chunk -  end - -  def test_regexp_chunk_should_add_question_mark_for_optionals -    s = ROUTING::StaticSegment.new("/", :optional => true) -    assert_equal "/?", s.regexp_chunk - -    s = ROUTING::StaticSegment.new("hello", :optional => true) -    assert_equal "(?:hello)?", s.regexp_chunk -  end -end - -class DynamicSegmentTest < Test::Unit::TestCase -  def segment(options = {}) -    unless @segment -      @segment = ROUTING::DynamicSegment.new(:a, options) -    end -    @segment -  end - -  def test_extract_value -    s = ROUTING::DynamicSegment.new(:a) - -    hash = {:a => '10', :b => '20'} -    assert_equal '10', eval(s.extract_value) - -    hash = {:b => '20'} -    assert_equal nil, eval(s.extract_value) - -    s.default = '20' -    assert_equal '20', eval(s.extract_value) -  end - -  def test_default_local_name -    assert_equal 'a_value', segment.local_name, -      "Unexpected name -- all value_check tests will fail!" -  end - -  def test_presence_value_check -    a_value = 10 -    assert eval(segment.value_check) -  end - -  def test_regexp_value_check_rejects_nil -    segment = segment(:regexp => /\d+/) - -    a_value = nil -    assert !eval(segment.value_check) -  end - -  def test_optional_regexp_value_check_should_accept_nil -    segment = segment(:regexp => /\d+/, :optional => true) - -    a_value = nil -    assert eval(segment.value_check) -  end - -  def test_regexp_value_check_rejects_no_match -    segment = segment(:regexp => /\d+/) - -    a_value = "Hello20World" -    assert !eval(segment.value_check) - -    a_value = "20Hi" -    assert !eval(segment.value_check) -  end - -  def test_regexp_value_check_accepts_match -    segment = segment(:regexp => /\d+/) -    a_value = "30" -    assert eval(segment.value_check) -  end - -  def test_value_check_fails_on_nil -    a_value = nil -    assert ! eval(segment.value_check) -  end - -  def test_optional_value_needs_no_check -    segment = segment(:optional => true) - -    a_value = nil -    assert_equal nil, segment.value_check -  end - -  def test_regexp_value_check_should_accept_match_with_default -    segment = segment(:regexp => /\d+/, :default => '200') - -    a_value = '100' -    assert eval(segment.value_check) -  end - -  def test_expiry_should_not_trigger_once_expired -    expired = true -    hash = merged = {:a => 2, :b => 3} -    options = {:b => 3} -    expire_on = Hash.new { raise 'No!!!' } - -    eval(segment.expiry_statement) -  rescue RuntimeError -    flunk "Expiry check should not have occurred!" -  end - -  def test_expiry_should_occur_according_to_expire_on -    expired = false -    hash = merged = {:a => 2, :b => 3} -    options = {:b => 3} - -    expire_on = {:b => true, :a => false} -    eval(segment.expiry_statement) -    assert !expired -    assert_equal({:a => 2, :b => 3}, hash) - -    expire_on = {:b => true, :a => true} -    eval(segment.expiry_statement) -    assert expired -    assert_equal({:b => 3}, hash) -  end - -  def test_extraction_code_should_return_on_nil -    hash = merged = {:b => 3} -    options = {:b => 3} -    a_value = nil - -    # Local jump because of return inside eval. -    assert_raise(LocalJumpError) { eval(segment.extraction_code) } -  end - -  def test_extraction_code_should_return_on_mismatch -    segment = segment(:regexp => /\d+/) -    hash = merged = {:a => 'Hi', :b => '3'} -    options = {:b => '3'} -    a_value = nil - -    # Local jump because of return inside eval. -    assert_raise(LocalJumpError) { eval(segment.extraction_code) } -  end - -  def test_extraction_code_should_accept_value_and_set_local -    hash = merged = {:a => 'Hi', :b => '3'} -    options = {:b => '3'} -    a_value = nil -    expired = true - -    eval(segment.extraction_code) -    assert_equal 'Hi', a_value -  end - -  def test_extraction_should_work_without_value_check -    segment.default = 'hi' -    hash = merged = {:b => '3'} -    options = {:b => '3'} -    a_value = nil -    expired = true - -    eval(segment.extraction_code) -    assert_equal 'hi', a_value -  end - -  def test_extraction_code_should_perform_expiry -    expired = false -    hash = merged = {:a => 'Hi', :b => '3'} -    options = {:b => '3'} -    expire_on = {:a => true} -    a_value = nil - -    eval(segment.extraction_code) -    assert_equal 'Hi', a_value -    assert expired -    assert_equal options, hash -  end - -  def test_interpolation_chunk_should_replace_value -    a_value = 'Hi' -    assert_equal a_value, eval(%("#{segment.interpolation_chunk}")) -  end - -  def test_interpolation_chunk_should_accept_nil -    a_value = nil -    assert_equal '', eval(%("#{segment.interpolation_chunk('a_value')}")) -  end - -  def test_value_regexp_should_be_nil_without_regexp -    assert_equal nil, segment.value_regexp -  end - -  def test_value_regexp_should_match_exacly -    segment = segment(:regexp => /\d+/) -    assert_no_match segment.value_regexp, "Hello 10 World" -    assert_no_match segment.value_regexp, "Hello 10" -    assert_no_match segment.value_regexp, "10 World" -    assert_match segment.value_regexp, "10" -  end - -  def test_regexp_chunk_should_return_string -    segment = segment(:regexp => /\d+/) -    assert_kind_of String, segment.regexp_chunk -  end - -  def test_build_pattern_non_optional_with_no_captures -    # Non optional -    a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /\d+/) -    assert_equal "(\\d+)stuff", a_segment.build_pattern('stuff') -  end - -  def test_build_pattern_non_optional_with_captures -    # Non optional -    a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /(\d+)(.*?)/) -    assert_equal "((\\d+)(.*?))stuff", a_segment.build_pattern('stuff') -  end - -  def test_optionality_implied -    a_segment = ROUTING::DynamicSegment.new(:id) -    assert a_segment.optionality_implied? - -    a_segment = ROUTING::DynamicSegment.new(:action) -    assert a_segment.optionality_implied? -  end - -  def test_modifiers_must_be_handled_sensibly -    a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /david|jamis/i) -    assert_equal "((?i-mx:david|jamis))stuff", a_segment.build_pattern('stuff') -    a_segment = ROUTING::DynamicSegment.new(nil, :regexp =>  /david|jamis/x) -    assert_equal "((?x-mi:david|jamis))stuff", a_segment.build_pattern('stuff') -    a_segment = ROUTING::DynamicSegment.new(nil, :regexp => /david|jamis/) -    assert_equal "(david|jamis)stuff", a_segment.build_pattern('stuff') -  end -end - -class ControllerSegmentTest < Test::Unit::TestCase -  def test_regexp_should_only_match_possible_controllers -    ActionController::Routing.with_controllers %w(admin/accounts admin/users account pages) do -      cs = ROUTING::ControllerSegment.new :controller -      regexp = %r{\A#{cs.regexp_chunk}\Z} - -      ActionController::Routing.possible_controllers.each do |name| -        assert_match regexp, name -        assert_no_match regexp, "#{name}_fake" - -        match = regexp.match name -        assert_equal name, match[1] -      end -    end -  end -end - -class PathSegmentTest < Test::Unit::TestCase -  def segment(options = {}) -    unless @segment -      @segment = ROUTING::PathSegment.new(:path, options) -    end -    @segment -  end - -  def test_regexp_chunk_should_return_string -    segment = segment(:regexp => /[a-z]+/) -    assert_kind_of String, segment.regexp_chunk -  end - -  def test_regexp_chunk_should_be_wrapped_with_parenthesis -    segment = segment(:regexp => /[a-z]+/) -    assert_equal "([a-z]+)", segment.regexp_chunk -  end - -  def test_regexp_chunk_should_respect_options -    segment = segment(:regexp => /[a-z]+/i) -    assert_equal "((?i-mx:[a-z]+))", segment.regexp_chunk -  end -end - -class RouteBuilderTest < Test::Unit::TestCase -  def builder -    @builder ||= ROUTING::RouteBuilder.new -  end - -  def build(path, options) -    builder.build(path, options) -  end - -  def test_options_should_not_be_modified -    requirements1 = { :id => /\w+/, :controller => /(?:[a-z](?:-?[a-z]+)*)/ } -    requirements2 = requirements1.dup - -    assert_equal requirements1, requirements2 - -    with_options(:controller => 'folder', -                 :requirements => requirements2) do |m| -      m.build 'folders/new', :action => 'new' -    end - -    assert_equal requirements1, requirements2 -  end - -  def test_segment_for_static -    segment, rest = builder.segment_for 'ulysses' -    assert_equal '', rest -    assert_kind_of ROUTING::StaticSegment, segment -    assert_equal 'ulysses', segment.value -  end - -  def test_segment_for_action -    segment, rest = builder.segment_for ':action' -    assert_equal '', rest -    assert_kind_of ROUTING::DynamicSegment, segment -    assert_equal :action, segment.key -    assert_equal 'index', segment.default -  end - -  def test_segment_for_dynamic -    segment, rest = builder.segment_for ':login' -    assert_equal '', rest -    assert_kind_of ROUTING::DynamicSegment, segment -    assert_equal :login, segment.key -    assert_equal nil, segment.default -    assert ! segment.optional? -  end - -  def test_segment_for_with_rest -    segment, rest = builder.segment_for ':login/:action' -    assert_equal :login, segment.key -    assert_equal '/:action', rest -    segment, rest = builder.segment_for rest -    assert_equal '/', segment.value -    assert_equal ':action', rest -    segment, rest = builder.segment_for rest -    assert_equal :action, segment.key -    assert_equal '', rest -  end - -  def test_segments_for -    segments = builder.segments_for_route_path '/:controller/:action/:id' - -    assert_kind_of ROUTING::DividerSegment, segments[0] -    assert_equal '/', segments[2].value - -    assert_kind_of ROUTING::DynamicSegment, segments[1] -    assert_equal :controller, segments[1].key - -    assert_kind_of ROUTING::DividerSegment, segments[2] -    assert_equal '/', segments[2].value - -    assert_kind_of ROUTING::DynamicSegment, segments[3] -    assert_equal :action, segments[3].key - -    assert_kind_of ROUTING::DividerSegment, segments[4] -    assert_equal '/', segments[4].value - -    assert_kind_of ROUTING::DynamicSegment, segments[5] -    assert_equal :id, segments[5].key -  end - -  def test_segment_for_action -    s, r = builder.segment_for(':action/something/else') -    assert_equal '/something/else', r -    assert_equal :action, s.key -  end - -  def test_action_default_should_not_trigger_on_prefix -    s, r = builder.segment_for ':action_name/something/else' -    assert_equal '/something/else', r -    assert_equal :action_name, s.key -    assert_equal nil, s.default -  end - -  def test_divide_route_options -    segments = builder.segments_for_route_path '/cars/:action/:person/:car/' -    defaults, requirements = builder.divide_route_options(segments, -      :action => 'buy', :person => /\w+/, :car => /\w+/, -      :defaults => {:person => nil, :car => nil} -    ) - -    assert_equal({:action => 'buy', :person => nil, :car => nil}, defaults) -    assert_equal({:person => /\w+/, :car => /\w+/}, requirements) -  end - -  def test_assign_route_options -    segments = builder.segments_for_route_path '/cars/:action/:person/:car/' -    defaults = {:action => 'buy', :person => nil, :car => nil} -    requirements = {:person => /\w+/, :car => /\w+/} - -    route_requirements = builder.assign_route_options(segments, defaults, requirements) -    assert_equal({}, route_requirements) - -    assert_equal :action, segments[3].key -    assert_equal 'buy', segments[3].default - -    assert_equal :person, segments[5].key -    assert_equal %r/\w+/, segments[5].regexp -    assert segments[5].optional? - -    assert_equal :car, segments[7].key -    assert_equal %r/\w+/, segments[7].regexp -    assert segments[7].optional? -  end - -  def test_assign_route_options_with_anchor_chars -    segments = builder.segments_for_route_path '/cars/:action/:person/:car/' -    defaults = {:action => 'buy', :person => nil, :car => nil} -    requirements = {:person => /\w+/, :car => /^\w+$/} - -    assert_raise ArgumentError do -      route_requirements = builder.assign_route_options(segments, defaults, requirements) -    end - -    requirements[:car] = /[^\/]+/ -    route_requirements = builder.assign_route_options(segments, defaults, requirements) -  end - -  def test_optional_segments_preceding_required_segments -    segments = builder.segments_for_route_path '/cars/:action/:person/:car/' -    defaults = {:action => 'buy', :person => nil, :car => "model-t"} -    assert builder.assign_route_options(segments, defaults, {}).empty? - -    0.upto(1) { |i| assert !segments[i].optional?, "segment #{i} is optional and it shouldn't be" } -    assert segments[2].optional? - -    assert_equal nil, builder.warn_output # should only warn on the :person segment -  end - -  def test_segmentation_of_dot_path -    segments = builder.segments_for_route_path '/books/:action.rss' -    assert builder.assign_route_options(segments, {}, {}).empty? -    assert_equal 6, segments.length # "/", "books", "/", ":action", ".", "rss" -    assert !segments.any? { |seg| seg.optional? } -  end - -  def test_segmentation_of_dynamic_dot_path -    segments = builder.segments_for_route_path '/books/:action.:format' -    assert builder.assign_route_options(segments, {}, {}).empty? -    assert_equal 6, segments.length # "/", "books", "/", ":action", ".", ":format" -    assert !segments.any? { |seg| seg.optional? } -    assert_kind_of ROUTING::DynamicSegment, segments.last -  end - -  def test_assignment_of_default_options -    segments = builder.segments_for_route_path '/:controller/:action/:id/' -    action, id = segments[-4], segments[-2] - -    assert_equal :action, action.key -    assert_equal :id, id.key -    assert ! action.optional? -    assert ! id.optional? - -    builder.assign_default_route_options(segments) - -    assert_equal 'index', action.default -    assert action.optional? -    assert id.optional? -  end - -  def test_assignment_of_default_options_respects_existing_defaults -    segments = builder.segments_for_route_path '/:controller/:action/:id/' -    action, id = segments[-4], segments[-2] - -    assert_equal :action, action.key -    assert_equal :id, id.key -    action.default = 'show' -    action.is_optional = true - -    id.default = 'Welcome' -    id.is_optional = true - -    builder.assign_default_route_options(segments) - -    assert_equal 'show', action.default -    assert action.optional? -    assert_equal 'Welcome', id.default -    assert id.optional? -  end - -  def test_assignment_of_default_options_respects_regexps -    segments = builder.segments_for_route_path '/:controller/:action/:id/' -    action = segments[-4] - -    assert_equal :action, action.key -    segments[-4] = ROUTING::DynamicSegment.new(:action, :regexp => /show|in/) - -    builder.assign_default_route_options(segments) - -    assert_equal nil, action.default -    assert ! action.optional? -  end - -  def test_assignment_of_is_optional_when_default -    segments = builder.segments_for_route_path '/books/:action.rss' -    assert_equal segments[3].key, :action -    segments[3].default = 'changes' -    builder.ensure_required_segments(segments) -    assert ! segments[3].optional? -  end - -  def test_is_optional_is_assigned_to_default_segments -    segments = builder.segments_for_route_path '/books/:action' -    builder.assign_route_options(segments, {:action => 'index'}, {}) - -    assert_equal segments[3].key, :action -    assert segments[3].optional? -    assert_kind_of ROUTING::DividerSegment, segments[2] -    assert segments[2].optional? -  end - -  # XXX is optional not being set right? -  # /blah/:defaulted_segment <-- is the second slash optional? it should be. - -  def test_route_build -    ActionController::Routing.with_controllers %w(users pages) do -      r = builder.build '/:controller/:action/:id/', :action => nil - -      [0, 2, 4].each do |i| -        assert_kind_of ROUTING::DividerSegment, r.segments[i] -        assert_equal '/', r.segments[i].value -        assert r.segments[i].optional? if i > 1 -      end - -      assert_kind_of ROUTING::DynamicSegment, r.segments[1] -      assert_equal :controller, r.segments[1].key -      assert_equal nil, r.segments[1].default - -      assert_kind_of ROUTING::DynamicSegment, r.segments[3] -      assert_equal :action, r.segments[3].key -      assert_equal 'index', r.segments[3].default - -      assert_kind_of ROUTING::DynamicSegment, r.segments[5] -      assert_equal :id, r.segments[5].key -      assert r.segments[5].optional? -    end -  end - -  def test_slashes_are_implied -    routes = [ -      builder.build('/:controller/:action/:id/', :action => nil), -      builder.build('/:controller/:action/:id', :action => nil), -      builder.build(':controller/:action/:id', :action => nil), -      builder.build('/:controller/:action/:id/', :action => nil) -    ] -    expected = routes.first.segments.length -    routes.each_with_index do |route, i| -      found = route.segments.length -      assert_equal expected, found, "Route #{i + 1} has #{found} segments, expected #{expected}" -    end -  end -end -  class RoutingTest < Test::Unit::TestCase    def test_possible_controllers      true_controller_paths = ActionController::Routing.controller_paths @@ -1091,8 +507,7 @@ class LegacyRouteSetTests < Test::Unit::TestCase        map.connect '*path', :controller => 'content', :action => 'show_file'      end -    recall_path = ActionController::Routing::PathSegment::Result.new(%w(pages boo)) -    assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => recall_path) +    assert_equal '/pages/boo', rs.generate({}, :controller => 'content', :action => 'show_file', :path => %w(pages boo))    end    def test_backwards @@ -1408,161 +823,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase    end  end -class RouteTest < Test::Unit::TestCase -  def setup -    @route = ROUTING::Route.new -  end - -  def slash_segment(is_optional = false) -    ROUTING::DividerSegment.new('/', :optional => is_optional) -  end - -  def default_route -    unless defined?(@default_route) -      segments = [] -      segments << ROUTING::StaticSegment.new('/', :raw => true) -      segments << ROUTING::DynamicSegment.new(:controller) -      segments << slash_segment(:optional) -      segments << ROUTING::DynamicSegment.new(:action, :default => 'index', :optional => true) -      segments << slash_segment(:optional) -      segments << ROUTING::DynamicSegment.new(:id, :optional => true) -      segments << slash_segment(:optional) -      @default_route = ROUTING::Route.new(segments).freeze -    end -    @default_route -  end - -  def test_default_route_recognition -    expected = {:controller => 'accounts', :action => 'show', :id => '10'} -    assert_equal expected, default_route.recognize('/accounts/show/10') -    assert_equal expected, default_route.recognize('/accounts/show/10/') - -    expected[:id] = 'jamis' -    assert_equal expected, default_route.recognize('/accounts/show/jamis/') - -    expected.delete :id -    assert_equal expected, default_route.recognize('/accounts/show') -    assert_equal expected, default_route.recognize('/accounts/show/') - -    expected[:action] = 'index' -    assert_equal expected, default_route.recognize('/accounts/') -    assert_equal expected, default_route.recognize('/accounts') - -    assert_equal nil, default_route.recognize('/') -    assert_equal nil, default_route.recognize('/accounts/how/goood/it/is/to/be/free') -  end - -  def test_default_route_should_omit_default_action -    o = {:controller => 'accounts', :action => 'index'} -    assert_equal '/accounts', default_route.generate(o, o, {}) -  end - -  def test_default_route_should_include_default_action_when_id_present -    o = {:controller => 'accounts', :action => 'index', :id => '20'} -    assert_equal '/accounts/index/20', default_route.generate(o, o, {}) -  end - -  def test_default_route_should_work_with_action_but_no_id -    o = {:controller => 'accounts', :action => 'list_all'} -    assert_equal '/accounts/list_all', default_route.generate(o, o, {}) -  end - -  def test_default_route_should_uri_escape_pluses -    expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' } -    assert_equal expected, default_route.recognize('/accounts/show/hello world') -    assert_equal expected, default_route.recognize('/accounts/show/hello%20world') -    assert_equal '/accounts/show/hello%20world', default_route.generate(expected, expected, {}) - -    expected[:id] = 'hello+world' -    assert_equal expected, default_route.recognize('/accounts/show/hello+world') -    assert_equal expected, default_route.recognize('/accounts/show/hello%2Bworld') -    assert_equal '/accounts/show/hello+world', default_route.generate(expected, expected, {}) -  end - -  def test_matches_controller_and_action -    # requirement_for should only be called for the action and controller _once_ -    @route.expects(:requirement_for).with(:controller).times(1).returns('pages') -    @route.expects(:requirement_for).with(:action).times(1).returns('show') - -    @route.requirements = {:controller => 'pages', :action => 'show'} -    assert @route.matches_controller_and_action?('pages', 'show') -    assert !@route.matches_controller_and_action?('not_pages', 'show') -    assert !@route.matches_controller_and_action?('pages', 'not_show') -  end - -  def test_parameter_shell -    page_url = ROUTING::Route.new -    page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/} -    assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell) -  end - -  def test_defaults -    route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html" -    assert_equal( -      { :controller => "users", :action => "show", :format => "html" }, -      route.defaults) -  end - -  def test_builder_complains_without_controller -    assert_raise(ArgumentError) do -      ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index" -    end -  end - -  def test_significant_keys_for_default_route -    keys = default_route.significant_keys.sort_by {|k| k.to_s } -    assert_equal [:action, :controller, :id], keys -  end - -  def test_significant_keys -    segments = [] -    segments << ROUTING::StaticSegment.new('/', :raw => true) -    segments << ROUTING::StaticSegment.new('user') -    segments << ROUTING::StaticSegment.new('/', :raw => true, :optional => true) -    segments << ROUTING::DynamicSegment.new(:user) -    segments << ROUTING::StaticSegment.new('/', :raw => true, :optional => true) - -    requirements = {:controller => 'users', :action => 'show'} - -    user_url = ROUTING::Route.new(segments, requirements) -    keys = user_url.significant_keys.sort_by { |k| k.to_s } -    assert_equal [:action, :controller, :user], keys -  end - -  def test_build_empty_query_string -    assert_equal '', @route.build_query_string({}) -  end - -  def test_build_query_string_with_nil_value -    assert_equal '', @route.build_query_string({:x => nil}) -  end - -  def test_simple_build_query_string -    assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => '1', :y => '2')) -  end - -  def test_convert_ints_build_query_string -    assert_equal '?x=1&y=2', order_query_string(@route.build_query_string(:x => 1, :y => 2)) -  end - -  def test_escape_spaces_build_query_string -    assert_equal '?x=hello+world&y=goodbye+world', order_query_string(@route.build_query_string(:x => 'hello world', :y => 'goodbye world')) -  end - -  def test_expand_array_build_query_string -    assert_equal '?x%5B%5D=1&x%5B%5D=2', order_query_string(@route.build_query_string(:x => [1, 2])) -  end - -  def test_escape_spaces_build_query_string_selected_keys -    assert_equal '?x=hello+world', order_query_string(@route.build_query_string({:x => 'hello world', :y => 'goodbye world'}, [:x])) -  end - -  private -    def order_query_string(qs) -      '?' + qs[1..-1].split('&').sort.join('&') -    end -end -  class RouteSetTest < ActiveSupport::TestCase    def set      @set ||= ROUTING::RouteSet.new @@ -1572,6 +832,19 @@ class RouteSetTest < ActiveSupport::TestCase      @request ||= ActionController::TestRequest.new    end +  def default_route_set +    @default_route_set ||= begin +      set = nil +      ActionController::Routing.with_controllers(['accounts']) do +        set = ROUTING::RouteSet.new +        set.draw do |map| +          map.connect '/:controller/:action/:id/' +        end +      end +      set +    end +  end +    def test_generate_extras      set.draw { |m| m.connect ':controller/:action/:id' }      path, extras = set.generate_extras(:controller => "foo", :action => "bar", :id => 15, :this => "hello", :that => "world") @@ -2457,6 +1730,213 @@ class RouteSetTest < ActiveSupport::TestCase      assert_equal({:controller => 'pages', :action => 'show', :name => :as_symbol}, set.recognize_path('/named'))    end + +  def test_interpolation_chunk_should_respect_raw +    ActionController::Routing.with_controllers(['hello']) do +      set.draw do |map| +        map.connect '/Hello World', :controller => 'hello' +      end + +      assert_equal '/Hello%20World', set.generate(:controller => 'hello') +      assert_equal({:controller => "hello", :action => "index"}, set.recognize_path('/Hello World')) +      assert_raise(ActionController::RoutingError) { set.recognize_path('/Hello%20World') } +    end +  end + +  def test_value_should_not_be_double_unescaped +    ActionController::Routing.with_controllers(['foo']) do +      set.draw do |map| +        map.connect '/Карта', :controller => 'foo' +      end + +      assert_equal '/%D0%9A%D0%B0%D1%80%D1%82%D0%B0', set.generate(:controller => 'foo') +      assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Карта')) +      assert_raise(ActionController::RoutingError) { set.recognize_path('/%D0%9A%D0%B0%D1%80%D1%82%D0%B0') } +    end +  end + +  def test_regexp_chunk_should_escape_specials +    ActionController::Routing.with_controllers(['foo', 'bar']) do +      set.draw do |map| +        map.connect '/Hello*World', :controller => 'foo' +        map.connect '/HelloWorld', :controller => 'bar' +      end + +      assert_equal '/Hello*World', set.generate(:controller => 'foo') +      assert_equal '/HelloWorld', set.generate(:controller => 'bar') + +      assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/Hello*World')) +      assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/HelloWorld')) +    end +  end + +  def test_regexp_chunk_should_add_question_mark_for_optionals +    ActionController::Routing.with_controllers(['foo', 'bar']) do +      set.draw do |map| +        map.connect '/', :controller => 'foo' +        map.connect '/hello', :controller => 'bar' +      end + +      assert_equal '/', set.generate(:controller => 'foo') +      assert_equal '/hello', set.generate(:controller => 'bar') + +      assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/')) +      assert_equal({:controller => "bar", :action => "index"}, set.recognize_path('/hello')) +    end +  end + +  def test_assign_route_options_with_anchor_chars +    ActionController::Routing.with_controllers(['cars']) do +      set.draw do |map| +        map.connect '/cars/:action/:person/:car/', :controller => 'cars' +      end + +      assert_equal '/cars/buy/1/2', set.generate(:controller => 'cars', :action => 'buy', :person => '1', :car => '2') + +      assert_equal({:controller => "cars", :action => "buy", :person => "1", :car => "2"}, set.recognize_path('/cars/buy/1/2')) +    end +  end + +  def test_segmentation_of_dot_path +    ActionController::Routing.with_controllers(['books']) do +      set.draw do |map| +        map.connect '/books/:action.rss', :controller => 'books' +      end + +      assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list') + +      assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list.rss')) +    end +  end + +  def test_segmentation_of_dynamic_dot_path +    ActionController::Routing.with_controllers(['books']) do +      set.draw do |map| +        map.connect '/books/:action.:format', :controller => 'books' +      end + +      assert_equal '/books/list.rss', set.generate(:controller => 'books', :action => 'list', :format => 'rss') +      assert_equal '/books/list.xml', set.generate(:controller => 'books', :action => 'list', :format => 'xml') +      assert_equal '/books/list', set.generate(:controller => 'books', :action => 'list') +      assert_equal '/books', set.generate(:controller => 'books', :action => 'index') + +      assert_equal({:controller => "books", :action => "list", :format => "rss"}, set.recognize_path('/books/list.rss')) +      assert_equal({:controller => "books", :action => "list", :format => "xml"}, set.recognize_path('/books/list.xml')) +      assert_equal({:controller => "books", :action => "list"}, set.recognize_path('/books/list')) +      assert_equal({:controller => "books", :action => "index"}, set.recognize_path('/books')) +    end +  end + +  def test_slashes_are_implied +    ActionController::Routing.with_controllers(['foo']) do +      ['/:controller/:action/:id/', '/:controller/:action/:id', +        ':controller/:action/:id', '/:controller/:action/:id/' +      ].each do |path| +        @set = nil +        set.draw { |map| map.connect(path) } + +        assert_equal '/foo', set.generate(:controller => 'foo', :action => 'index') +        assert_equal '/foo/list', set.generate(:controller => 'foo', :action => 'list') +        assert_equal '/foo/show/1', set.generate(:controller => 'foo', :action => 'show', :id => '1') + +        assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/foo')) +        assert_equal({:controller => "foo", :action => "index"}, set.recognize_path('/foo/index')) +        assert_equal({:controller => "foo", :action => "list"}, set.recognize_path('/foo/list')) +        assert_equal({:controller => "foo", :action => "show", :id => "1"}, set.recognize_path('/foo/show/1')) +      end +    end +  end + +  def test_default_route_recognition +    expected = {:controller => 'accounts', :action => 'show', :id => '10'} +    assert_equal expected, default_route_set.recognize_path('/accounts/show/10') +    assert_equal expected, default_route_set.recognize_path('/accounts/show/10/') + +    expected[:id] = 'jamis' +    assert_equal expected, default_route_set.recognize_path('/accounts/show/jamis/') + +    expected.delete :id +    assert_equal expected, default_route_set.recognize_path('/accounts/show') +    assert_equal expected, default_route_set.recognize_path('/accounts/show/') + +    expected[:action] = 'index' +    assert_equal expected, default_route_set.recognize_path('/accounts/') +    assert_equal expected, default_route_set.recognize_path('/accounts') + +    assert_raise(ActionController::RoutingError) { default_route_set.recognize_path('/') } +    assert_raise(ActionController::RoutingError) { default_route_set.recognize_path('/accounts/how/goood/it/is/to/be/free') } +  end + +  def test_default_route_should_omit_default_action +    assert_equal '/accounts', default_route_set.generate({:controller => 'accounts', :action => 'index'}) +  end + +  def test_default_route_should_include_default_action_when_id_present +    assert_equal '/accounts/index/20', default_route_set.generate({:controller => 'accounts', :action => 'index', :id => '20'}) +  end + +  def test_default_route_should_work_with_action_but_no_id +    assert_equal '/accounts/list_all', default_route_set.generate({:controller => 'accounts', :action => 'list_all'}) +  end + +  def test_default_route_should_uri_escape_pluses +    expected = { :controller => 'accounts', :action => 'show', :id => 'hello world' } +    assert_equal expected, default_route_set.recognize_path('/accounts/show/hello world') +    assert_equal expected, default_route_set.recognize_path('/accounts/show/hello%20world') +    assert_equal '/accounts/show/hello%20world', default_route_set.generate(expected, expected) + +    expected[:id] = 'hello+world' +    assert_equal expected, default_route_set.recognize_path('/accounts/show/hello+world') +    assert_equal expected, default_route_set.recognize_path('/accounts/show/hello%2Bworld') +    assert_equal '/accounts/show/hello+world', default_route_set.generate(expected, expected) +  end + +  def test_parameter_shell +    page_url = ROUTING::Route.new +    page_url.requirements = {:controller => 'pages', :action => 'show', :id => /\d+/} +    assert_equal({:controller => 'pages', :action => 'show'}, page_url.parameter_shell) +  end + +  def test_defaults +    route = ROUTING::RouteBuilder.new.build '/users/:id.:format', :controller => "users", :action => "show", :format => "html" +    assert_equal( +      { :controller => "users", :action => "show", :format => "html" }, +      route.defaults) +  end + +  def test_builder_complains_without_controller +    assert_raise(ArgumentError) do +      ROUTING::RouteBuilder.new.build '/contact', :contoller => "contact", :action => "index" +    end +  end + +  def test_build_empty_query_string +    assert_equal '/foo', default_route_set.generate({:controller => 'foo'}) +  end + +  def test_build_query_string_with_nil_value +    assert_equal '/foo', default_route_set.generate({:controller => 'foo', :x => nil}) +  end + +  def test_simple_build_query_string +    assert_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => '1', :y => '2'}) +  end + +  def test_convert_ints_build_query_string +    assert_equal '/foo?x=1&y=2', default_route_set.generate({:controller => 'foo', :x => 1, :y => 2}) +  end + +  def test_escape_spaces_build_query_string +    assert_equal '/foo?x=hello+world&y=goodbye+world', default_route_set.generate({:controller => 'foo', :x => 'hello world', :y => 'goodbye world'}) +  end + +  def test_expand_array_build_query_string +    assert_equal '/foo?x%5B%5D=1&x%5B%5D=2', default_route_set.generate({:controller => 'foo', :x => [1, 2]}) +  end + +  def test_escape_spaces_build_query_string_selected_keys +    assert_equal '/foo?x=hello+world', default_route_set.generate({:controller => 'foo', :x => 'hello world'}) +  end  end  class RouteLoadingTest < Test::Unit::TestCase | 
