From 8e56f5ea3e5394caa2ffee466a7395876c288c2a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 24 Jun 2005 16:40:01 +0000 Subject: Improved performance of Routes generation by a factor of 5 #1434 [Nicholas Seckar] Added named routes (NEEDS BETTER DESCRIPTION) #1434 [Nicholas Seckar] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1496 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/test/abstract_unit.rb | 2 +- actionpack/test/controller/routing_test.rb | 1020 +++++++++++++++------------- 2 files changed, 563 insertions(+), 459 deletions(-) (limited to 'actionpack/test') diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 4b244e9472..fae40cd8ac 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -9,4 +9,4 @@ require 'action_controller/test_process' ActionController::Base.logger = nil ActionController::Base.ignore_missing_templates = true -ActionController::Routing::Routes.reload \ No newline at end of file +ActionController::Routing::Routes.reload rescue nil diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 0f5987e69e..2e35320322 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -1,543 +1,647 @@ -# Code Generated by ZenTest v. 2.3.0 -# Couldn't find class for name Routing -# classname: asrt / meth = ratio% -# ActionController::Routing::RouteSet: 0 / 16 = 0.00% -# ActionController::Routing::RailsRoute: 0 / 4 = 0.00% -# ActionController::Routing::Route: 0 / 8 = 0.00% - require File.dirname(__FILE__) + '/../abstract_unit' require 'test/unit' -require 'cgi' -class FakeController - attr_reader :controller_path - attr_reader :name - def initialize(name, controller_path) - @name = name - @controller_path = controller_path - end - def kind_of?(x) - x === Class || x == FakeController - end -end +RunTimeTests = ARGV.include? 'time' -module Controllers - module Admin - UserController = FakeController.new 'Admin::UserController', 'admin/user' - AccessController = FakeController.new 'Admin::AccessController', 'admin/access' +module ActionController::CodeGeneration + +class SourceTests < Test::Unit::TestCase + attr_accessor :source + def setup + @source = Source.new end - module Editing - PageController = FakeController.new 'Editing::PageController', 'editing/page' - ImageController = FakeController.new 'Editing::ImageController', 'editing/image' + + def test_initial_state + assert_equal [], source.lines + assert_equal 0, source.indentation_level end - module User - NewsController = FakeController.new 'User::NewsController', 'user/news' - PaymentController = FakeController.new 'User::PaymentController', 'user/payment' + + def test_trivial_operations + source << "puts 'Hello World'" + assert_equal ["puts 'Hello World'"], source.lines + assert_equal "puts 'Hello World'", source.to_s + + source.line "puts 'Goodbye World'" + assert_equal ["puts 'Hello World'", "puts 'Goodbye World'"], source.lines + assert_equal "puts 'Hello World'\nputs 'Goodbye World'", source.to_s end - ContentController = FakeController.new 'ContentController', 'content' - ResourceController = FakeController.new 'ResourceController', 'resource' -end -# Extend the modules with the required methods... -[Controllers, Controllers::Admin, Controllers::Editing, Controllers::User].each do |mod| - mod.instance_eval('alias :const_available? :const_defined?') - mod.constants.each {|k| Object.const_set(k, mod.const_get(k))} # export the modules & controller classes. -end - + def test_indentation + source << "x = gets.to_i" + source << 'if x.odd?' + source.indent { source << "puts 'x is odd!'" } + source << 'else' + source.indent { source << "puts 'x is even!'" } + source << 'end' + + assert_equal ["x = gets.to_i", "if x.odd?", " puts 'x is odd!'", 'else', " puts 'x is even!'", 'end'], source.lines + + text = "x = gets.to_i +if x.odd? + puts 'x is odd!' +else + puts 'x is even!' +end" -class RouteTests < Test::Unit::TestCase - def route(*args) - return @route if @route && (args.empty? || @args == args) - @args = args - @route = ActionController::Routing::Route.new(*args) - return @route - end + assert_equal text, source.to_s + end +end +class CodeGeneratorTests < Test::Unit::TestCase + attr_accessor :generator def setup - self.route '/:controller/:action/:id' - @defaults = {:controller => 'content', :action => 'show', :id => '314'} + @generator = CodeGenerator.new end - - # Don't put a leading / on the url. - # Make sure the controller is one from the above fake Controllers module. - def verify_recognize(url, expected_options, reason='') - url = url.split('/') if url.kind_of? String - reason = ": #{reason}" unless reason.empty? - controller_class, options = @route.recognize(url) - assert_not_equal nil, controller_class, "#{@route.inspect} didn't recognize #{url}#{reason}\n #{options}" - assert_equal expected_options, options, "#{@route.inspect} produced wrong options for #{url}#{reason}" + + def test_initial_state + assert_equal [], generator.source.lines + assert_equal [], generator.locals end - - # The expected url should not have a leading / - # You can use @defaults if you want a set of plausible defaults - def verify_generate(expected_url, expected_extras, options, defaults, reason='') - reason = "#{reason}: " unless reason.empty? - components, extras = @route.generate(options, defaults) - assert_not_equal nil, components, "#{reason}#{@route.inspect} didn't generate for \n options = #{options.inspect}\n defaults = #{defaults.inspect}\n #{extras}" - assert_equal expected_extras, extras, "#{reason} #{@route.inspect}.generate: incorrect extra's" - assert_equal expected_url, components.join('/'), "#{reason} #{@route.inspect}.generate: incorrect url" + + def test_trivial_operations + ["puts 'Hello World'", "puts 'Goodbye World'"].each {|l| generator << l} + assert_equal ["puts 'Hello World'", "puts 'Goodbye World'"], generator.source.lines + assert_equal "puts 'Hello World'\nputs 'Goodbye World'", generator.to_s end - def test_recognize_default_unnested_with_action_and_id - verify_recognize('content/action/id', {:controller => 'content', :action => 'action', :id => 'id'}) - verify_recognize('content/show/10', {:controller => 'content', :action => 'show', :id => '10'}) - end - def test_generate_default_unnested_with_action_and_id_no_extras - verify_generate('content/action/id', {}, {:controller => 'content', :action => 'action', :id => 'id'}, @defaults) - verify_generate('content/show/10', {}, {:controller => 'content', :action => 'show', :id => '10'}, @defaults) - end - def test_generate_default_unnested_with_action_and_id - verify_generate('content/action/id', {:a => 'a'}, {:controller => 'content', :action => 'action', :id => 'id', :a => 'a'}, @defaults) - verify_generate('content/show/10', {:a => 'a'}, {:controller => 'content', :action => 'show', :id => '10', :a => 'a'}, @defaults) + def test_if + generator << "x = gets.to_i" + generator.if("x.odd?") { generator << "puts 'x is odd!'" } + + assert_equal "x = gets.to_i\nif x.odd?\n puts 'x is odd!'\nend", generator.to_s end - # Note that we can't put tests here for proper relative controller handline - # because that is handled by RouteSet. - def test_recognize_default_nested_with_action_and_id - verify_recognize('admin/user/action/id', {:controller => 'admin/user', :action => 'action', :id => 'id'}) - verify_recognize('admin/user/show/10', {:controller => 'admin/user', :action => 'show', :id => '10'}) + def test_else + test_if + generator.else { generator << "puts 'x is even!'" } + + assert_equal "x = gets.to_i\nif x.odd?\n puts 'x is odd!'\nelse \n puts 'x is even!'\nend", generator.to_s end - def test_generate_default_nested_with_action_and_id_no_extras - verify_generate('admin/user/action/id', {}, {:controller => 'admin/user', :action => 'action', :id => 'id'}, @defaults) - verify_generate('admin/user/show/10', {}, {:controller => 'admin/user', :action => 'show', :id => '10'}, @defaults) + + def test_dup + generator << 'x = 2' + generator.locals << :x + + g = generator.dup + assert_equal generator.source, g.source + assert_equal generator.locals, g.locals + + g << 'y = 3' + g.locals << :y + assert_equal [:x, :y], g.locals # Make sure they don't share the same array. + assert_equal [:x], generator.locals end - def test_generate_default_nested_with_action_and_id_relative_to_root - verify_generate('admin/user/action/id', {:a => 'a'}, {:controller => 'admin/user', :action => 'action', :id => 'id', :a => 'a'}, @defaults) - verify_generate('admin/user/show/10', {:a => 'a'}, {:controller => 'admin/user', :action => 'show', :id => '10', :a => 'a'}, @defaults) +end + +# XXX Extract to test/controller/fake_controllers.rb +module Object::Controllers + def self.const_available?(*args) + const_defined?(*args) end - def test_recognize_default_nested_with_action - verify_recognize('admin/user/action', {:controller => 'admin/user', :action => 'action'}) - verify_recognize('admin/user/show', {:controller => 'admin/user', :action => 'show'}) - end - def test_generate_default_nested_with_action_no_extras - verify_generate('admin/user/action', {}, {:controller => 'admin/user', :action => 'action'}, @defaults) - verify_generate('admin/user/show', {}, {:controller => 'admin/user', :action => 'show'}, @defaults) + class ContentController end - def test_generate_default_nested_with_action - verify_generate('admin/user/action', {:a => 'a'}, {:controller => 'admin/user', :action => 'action', :a => 'a'}, @defaults) - verify_generate('admin/user/show', {:a => 'a'}, {:controller => 'admin/user', :action => 'show', :a => 'a'}, @defaults) + module Admin + def self.const_available?(*args) + const_defined?(*args) + end + + class UserController + end end +end - def test_recognize_default_nested_with_id_and_index - verify_recognize('admin/user/index/hello', {:controller => 'admin/user', :id => 'hello', :action => 'index'}) - verify_recognize('admin/user/index/10', {:controller => 'admin/user', :id => "10", :action => 'index'}) - end - def test_generate_default_nested_with_id_no_extras - verify_generate('admin/user/index/hello', {}, {:controller => 'admin/user', :id => 'hello'}, @defaults) - verify_generate('admin/user/index/10', {}, {:controller => 'admin/user', :id => 10}, @defaults) + +class RecognitionTests < Test::Unit::TestCase + attr_accessor :generator + alias :g :generator + def setup + @generator = RecognitionGenerator.new end - def test_generate_default_nested_with_id - verify_generate('admin/user/index/hello', {:a => 'a'}, {:controller => 'admin/user', :id => 'hello', :a => 'a'}, @defaults) - verify_generate('admin/user/index/10', {:a => 'a'}, {:controller => 'admin/user', :id => 10, :a => 'a'}, @defaults) + + def go(components) + g.current = components.first + g.after = components[1..-1] || [] + g.go end - def test_recognize_default_nested - verify_recognize('admin/user', {:controller => 'admin/user', :action => 'index'}) - verify_recognize('admin/user', {:controller => 'admin/user', :action => 'index'}) - end - def test_generate_default_nested_no_extras - verify_generate('admin/user', {}, {:controller => 'admin/user'}, @defaults) - verify_generate('admin/user', {}, {:controller => 'admin/user'}, @defaults) - end - def test_generate_default_nested - verify_generate('admin/user', {:a => 'a'}, {:controller => 'admin/user', :a => 'a'}, @defaults) - verify_generate('admin/user', {:a => 'a'}, {:controller => 'admin/user', :a => 'a'}, @defaults) + def execute(path, show = false) + path = path.split('/') if path.is_a? String + source = "index, path = 0, #{path.inspect}\n#{g.to_s}" + puts source if show + r = eval source + r ? r.symbolize_keys : nil end - # Test generate with a default controller set. - def test_generate_default_controller - route '/:controller/:action/:id', :action => 'index', :id => nil, :controller => 'content' - @defaults[:controller] = 'resource' - - verify_generate('', {}, {:controller => 'content'}, @defaults) - verify_generate('', {}, {:controller => 'content', :action => 'index'}, @defaults) - verify_generate('content/not-index', {}, {:controller => 'content', :action => 'not-index'}, @defaults) - verify_generate('content/index/10', {}, {:controller => 'content', :id => 10}, @defaults) - verify_generate('content/index/hi', {}, {:controller => 'content', :action => 'index', :id => 'hi'}, @defaults) - verify_generate('', {:a => 'a'}, {:controller => 'content', :a => 'a'}, @defaults) - verify_generate('', {:a => 'a'}, {:controller => 'content', :a => 'a'}, @defaults) - - # Call some other generator tests - test_generate_default_unnested_with_action_and_id - test_generate_default_nested_with_action_and_id_no_extras - test_generate_default_nested_with_id - test_generate_default_nested_with_id_no_extras - end - - # Test generate with a default controller set. - def test_generate_default_controller - route '/:controller/:action/:id', :action => 'index', :id => nil, :controller => 'content' - @defaults[:controller] = 'resource' - verify_recognize('', {:controller => 'content', :action => 'index'}) - verify_recognize('content', {:controller => 'content', :action => 'index'}) - verify_recognize('content/index', {:controller => 'content', :action => 'index'}) - verify_recognize('content/index/10', {:controller => 'content', :action => 'index', :id => '10'}) - end - # Make sure generation & recognition don't happen in some cases: - def test_no_generate_on_no_options - assert_equal nil, @route.generate({}, {})[0] - end - def test_requirements - route 'some_static/route', :controller => 'content' - assert_equal nil, @route.generate({}, {})[0] - assert_equal nil, @route.generate({:controller => "dog"}, {})[0] - assert_equal nil, @route.recognize([])[0] - assert_equal nil, @route.recognize(%w{some_static route with more than expected})[0] - end + Static = ::ActionController::Routing::StaticComponent + Dynamic = ::ActionController::Routing::DynamicComponent + Path = ::ActionController::Routing::PathComponent + Controller = ::ActionController::Routing::ControllerComponent - def test_basecamp - route 'clients/', :controller => 'content' - verify_generate('clients', {}, {:controller => 'content'}, {}) # Would like to have clients/ - verify_generate('clients', {}, {:controller => 'content'}, @defaults) + def test_all_static + c = %w(hello world how are you).collect {|str| Static.new(str)} + + g.result :controller, "::Controllers::ContentController", true + g.constant_result :action, 'index' + + go c + + assert_nil execute('x') + assert_nil execute('hello/world/how') + assert_nil execute('hello/world/how/are') + assert_nil execute('hello/world/how/are/you/today') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hello/world/how/are/you')) end - def test_regexp_requirements - const_options = {:controller => 'content', :action => 'by_date'} - route ':year/:month/:day', const_options.merge(:year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/) - verify_recognize('2004/01/02', const_options.merge(:year => '2004', :month => '01', :day => '02')) - verify_recognize('2004/1/2', const_options.merge(:year => '2004', :month => '1', :day => '2')) - assert_equal nil, @route.recognize(%w{200 10 10})[0] - assert_equal nil, @route.recognize(%w{content show 10})[0] + def test_basic_dynamic + c = [Static.new("hi"), Dynamic.new(:action)] + g.result :controller, "::Controllers::ContentController", true + go c - verify_generate('2004/01/02', {}, const_options.merge(:year => '2004', :month => '01', :day => '02'), @defaults) - verify_generate('2004/1/2', {}, const_options.merge(:year => '2004', :month => '1', :day => '2'), @defaults) - assert_equal nil, @route.generate(const_options.merge(:year => '12004', :month => '01', :day => '02'), @defaults)[0] - end - - def test_regexp_requirement_not_in_path - assert_raises(ArgumentError) {route 'constant/path', :controller => 'content', :action => 'by_date', :something => /\d+/} - end - - def test_special_hash_names - route ':year/:name', :requirements => {:year => /\d{4}/, :controller => 'content'}, :defaults => {:name => 'ulysses'}, :action => 'show_bio_year' - verify_generate('1984', {}, {:controller => 'content', :action => 'show_bio_year', :year => 1984}, @defaults) - verify_generate('1984', {}, {:controller => 'content', :action => 'show_bio_year', :year => '1984'}, @defaults) - verify_generate('1984/odessys', {}, {:controller => 'content', :action => 'show_bio_year', :year => 1984, :name => 'odessys'}, @defaults) - verify_generate('1984/odessys', {}, {:controller => 'content', :action => 'show_bio_year', :year => '1984', :name => 'odessys'}, @defaults) - - verify_recognize('1984/odessys', {:controller => 'content', :action => 'show_bio_year', :year => '1984', :name => 'odessys'}) - verify_recognize('1984', {:controller => 'content', :action => 'show_bio_year', :year => '1984', :name => 'ulysses'}) + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_nil execute('hi') + assert_nil execute('hi/dude/what') + assert_equal({:controller => ::Controllers::ContentController, :action => 'dude'}, execute('hi/dude')) + end + + def test_dynamic_with_default + c = [Static.new("hi"), Dynamic.new(:action, :default => 'index')] + g.result :controller, "::Controllers::ContentController", true + go c + + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_nil execute('hi/dude/what') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hi')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hi/index')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'dude'}, execute('hi/dude')) + end + + def test_dynamic_with_string_condition + c = [Static.new("hi"), Dynamic.new(:action, :condition => 'index')] + g.result :controller, "::Controllers::ContentController", true + go c + + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_nil execute('hi') + assert_nil execute('hi/dude/what') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hi/index')) + assert_nil execute('hi/dude') end - def test_defaults_and_restrictions_for_items_not_in_path - assert_raises(ArgumentError) {route ':year/:name', :requirements => {:year => /\d{4}/}, :defaults => {:name => 'ulysses', :controller => 'content'}, :action => 'show_bio_year'} - assert_raises(ArgumentError) {route ':year/:name', :requirements => {:year => /\d{4}/, :imagine => /./}, :defaults => {:name => 'ulysses'}, :controller => 'content', :action => 'show_bio_year'} - end + def test_dynamic_with_regexp_condition + c = [Static.new("hi"), Dynamic.new(:action, :condition => /^[a-z]+$/)] + g.result :controller, "::Controllers::ContentController", true + go c + + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_nil execute('hi') + assert_nil execute('hi/FOXY') + assert_nil execute('hi/138708jkhdf') + assert_nil execute('hi/dkjfl8792343dfsf') + assert_nil execute('hi/dude/what') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hi/index')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'dude'}, execute('hi/dude')) + end - def test_optionals_with_regexp - route ':year/:month/:day', :requirements => {:year => /\d{4}/, :month => /\d{1,2}/, :day => /\d{1,2}/}, - :defaults => {:month => nil, :day => nil}, - :controller => 'content', :action => 'post_by_day' - verify_recognize('2005/06/12', {:controller => 'content', :action => 'post_by_day', :year => '2005', :month => '06', :day => '12'}) - verify_recognize('2005/06', {:controller => 'content', :action => 'post_by_day', :year => '2005', :month => '06'}) - verify_recognize('2005', {:controller => 'content', :action => 'post_by_day', :year => '2005'}) - - verify_generate('2005/06/12', {}, {:controller => 'content', :action => 'post_by_day', :year => '2005', :month => '06', :day => '12'}, @defaults) - verify_generate('2005/06', {}, {:controller => 'content', :action => 'post_by_day', :year => '2005', :month => '06'}, @defaults) - verify_generate('2005', {}, {:controller => 'content', :action => 'post_by_day', :year => '2005'}, @defaults) + def test_dynamic_with_regexp_and_default + c = [Static.new("hi"), Dynamic.new(:action, :condition => /^[a-z]+$/, :default => 'index')] + g.result :controller, "::Controllers::ContentController", true + go c + + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_nil execute('hi/FOXY') + assert_nil execute('hi/138708jkhdf') + assert_nil execute('hi/dkjfl8792343dfsf') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hi')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('hi/index')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'dude'}, execute('hi/dude')) + assert_nil execute('hi/dude/what') end - - def test_basecamp2 - route 'clients/:client_name/:project_name/', :controller => 'content', :action => 'start_page_redirect' - verify_recognize('clients/projects/2', {:controller => 'content', :client_name => 'projects', :project_name => '2', :action => 'start_page_redirect'}) + def test_path + c = [Static.new("hi"), Path.new(:file)] + g.result :controller, "::Controllers::ContentController", true + g.constant_result :action, "download" + + go c + + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_equal({:controller => ::Controllers::ContentController, :action => 'download', :file => []}, execute('hi')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'download', :file => %w(books agile_rails_dev.pdf)}, + execute('hi/books/agile_rails_dev.pdf')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'download', :file => ['dude']}, execute('hi/dude')) + assert_equal 'dude/what', execute('hi/dude/what')[:file].to_s end - def test_xal_style_dates - route 'articles/:category/:year/:month/:day', :controller => 'content', :action => 'list_articles', :category => 'all', :year => nil, :month => nil, :day =>nil - verify_recognize('articles', {:controller => 'content', :action => 'list_articles', :category => 'all'}) - verify_recognize('articles/porn', {:controller => 'content', :action => 'list_articles', :category => 'porn'}) - verify_recognize('articles/news/2005/08', {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '08'}) - verify_recognize('articles/news/2005/08/04', {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '08', :day => '04'}) - assert_equal nil, @route.recognize(%w{articles too many components are here})[0] - assert_equal nil, @route.recognize('')[0] - - verify_generate('articles', {}, {:controller => 'content', :action => 'list_articles'}, @defaults) - verify_generate('articles', {}, {:controller => 'content', :action => 'list_articles', :category => 'all'}, @defaults) - verify_generate('articles/news', {}, {:controller => 'content', :action => 'list_articles', :category => 'news'}, @defaults) - verify_generate('articles/news/2005', {}, {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005'}, @defaults) - verify_generate('articles/news/2005/05', {}, {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '05'}, @defaults) - verify_generate('articles/news/2005/05/16', {}, {:controller => 'content', :action => 'list_articles', :category => 'news', :year => '2005', :month => '05', :day => '16'}, @defaults) - - assert_equal nil, @route.generate({:controller => 'content', :action => 'list_articles', :day => '2'}, @defaults)[0] - # The above case should fail because a nil value cannot be present in a path. - # In other words, since :day is given, :month and :year must be given too. + def test_controller + c = [Static.new("hi"), Controller.new(:controller)] + g.constant_result :action, "hi" + + go c + + assert_nil execute('boo') + assert_nil execute('boo/blah') + assert_nil execute('hi/x') + assert_nil execute('hi/13870948') + assert_nil execute('hi/content/dog') + assert_nil execute('hi/admin/user/foo') + assert_equal({:controller => ::Controllers::ContentController, :action => 'hi'}, execute('hi/content')) + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'hi'}, execute('hi/admin/user')) end - - def test_no_controller - route 'some/:special/:route', :controller => 'a/missing/controller', :action => 'anything' - assert_raises(ActionController::RoutingError, "Should raise due to nonexistant controller") {@route.recognize(%w{some matching path})} - end - def test_bad_controller_path - assert_equal nil, @route.recognize(%w{no such controller fake_action id})[0] - end - def test_too_short_path - assert_equal nil, @route.recognize([])[0] - route 'some/static/route', :controller => 'content', :action => 'show' - assert_equal nil, route.recognize([])[0] - end - def test_too_long_path - assert_equal nil, @route.recognize(%w{content action id some extra components})[0] + def test_standard_route(time = ::RunTimeTests) + c = [Controller.new(:controller), Dynamic.new(:action, :default => 'index'), Dynamic.new(:id, :default => nil)] + go c + + # Make sure we get the right answers + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute('content')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'list'}, execute('content/list')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'show', :id => '10'}, execute('content/show/10')) + + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'index'}, execute('admin/user')) + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'list'}, execute('admin/user/list')) + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'show', :id => 'nseckar'}, execute('admin/user/show/nseckar')) + + assert_nil execute('content/show/10/20') + assert_nil execute('food') + + if time + source = "def self.execute(path) + path = path.split('/') if path.is_a? String + index = 0 + r = #{g.to_s} + end" + eval(source) + + GC.start + n = 1000 + time = Benchmark.realtime do n.times { + execute('content') + execute('content/list') + execute('content/show/10') + + execute('admin/user') + execute('admin/user/list') + execute('admin/user/show/nseckar') + + execute('admin/user/show/nseckar/dude') + execute('admin/why/show/nseckar') + execute('content/show/10/20') + execute('food') + } end + time -= Benchmark.realtime do n.times { } end + + + puts "\n\nRecognition:" + per_url = time / (n * 10) + + puts "#{per_url * 1000} ms/url" + puts "#{1 / per_url} urls/s\n\n" + end end - def test_incorrect_static_component - route 'some/static/route', :controller => 'content', :action => 'show' - assert_equal nil, route.recognize(%w{an non_matching path})[0] + + def test_default_route + g.result :controller, "::Controllers::ContentController", true + g.constant_result :action, 'index' + + go [] + + assert_nil execute('x') + assert_nil execute('hello/world/how') + assert_nil execute('hello/world/how/are') + assert_nil execute('hello/world/how/are/you/today') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, execute([])) end - def test_no_controller_defined - route 'some/:path/:without/a/controller' - assert_equal nil, route.recognize(%w{some matching path a controller})[0] +end + +class GenerationTests < Test::Unit::TestCase + attr_accessor :generator + alias :g :generator + def setup + @generator = GenerationGenerator.new # ha! end - def test_mismatching_requirements - route 'some/path', :controller => 'content', :action => 'fish' - assert_equal nil, route.generate({:controller => 'admin/user', :action => 'list'})[0] - assert_equal nil, route.generate({:controller => 'content', :action => 'list'})[0] - assert_equal nil, route.generate({:controller => 'admin/user', :action => 'fish'})[0] + def go(components) + g.current = components.first + g.after = components[1..-1] || [] + g.go end - def test_missing_value_for_generate - assert_equal nil, route.generate({})[0] # :controller is missing - end - def test_nils_inside_generated_path - route 'show/:year/:month/:day', :month => nil, :day => nil, :controller => 'content', :action => 'by_date' - assert_equal nil, route.generate({:year => 2005, :day => 10})[0] + def execute(options, recall, show = false) + source = "\n +expire_on = ::ActionController::Routing.expiry_hash(options, recall) +hash = merged = recall.merge(options) +not_expired = true + +#{g.to_s}\n\n" + puts source if show + eval(source) end - def test_expand_controller_path_non_nested_no_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{content} - assert_equal Controllers::ContentController, controller - assert_equal [], leftovers - end - def test_expand_controller_path_non_nested_with_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{content action id} - assert_equal Controllers::ContentController, controller - assert_equal %w{action id}, leftovers - end - def test_expand_controller_path_nested_no_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{admin user} - assert_equal Controllers::Admin::UserController, controller - assert_equal [], leftovers - end - def test_expand_controller_path_nested_no_leftover - controller, leftovers = @route.send :eat_path_to_controller, %w{admin user action id} - assert_equal Controllers::Admin::UserController, controller - assert_equal %w{action id}, leftovers - end - - def test_path_collection - route '*path_info', :controller => 'content', :action => 'fish' - verify_recognize'path/with/slashes', - :controller => 'content', :action => 'fish', :path_info => %w(path with slashes) - verify_generate('path/with/slashes', {}, - {:controller => 'content', :action => 'fish', :path_info => 'path/with/slashes'}, - {}) - end - def test_path_collection_with_array - route '*path_info', :controller => 'content', :action => 'fish' - verify_recognize'path/with/slashes', - :controller => 'content', :action => 'fish', :path_info => %w(path with slashes) - verify_generate('path/with/slashes', {}, - {:controller => 'content', :action => 'fish', :path_info => %w(path with slashes)}, - {}) - end - - def test_path_empty_list - route '*a', :controller => 'content' - verify_recognize '', :controller => 'content', :a => [] - end + Static = ::ActionController::Routing::StaticComponent + Dynamic = ::ActionController::Routing::DynamicComponent + Path = ::ActionController::Routing::PathComponent + Controller = ::ActionController::Routing::ControllerComponent - def test_special_characters - route ':id', :controller => 'content', :action => 'fish' - verify_recognize'id+with+spaces', - :controller => 'content', :action => 'fish', :id => 'id with spaces' - verify_generate('id+with+spaces', {}, - {:controller => 'content', :action => 'fish', :id => 'id with spaces'}, {}) - verify_recognize 'id%2Fwith%2Fslashes', - :controller => 'content', :action => 'fish', :id => 'id/with/slashes' - verify_generate('id%2Fwith%2Fslashes', {}, - {:controller => 'content', :action => 'fish', :id => 'id/with/slashes'}, {}) - end - - def test_generate_with_numeric_param - o = Object.new - def o.to_param() 10 end - verify_generate('content/action/10', {}, {:controller => 'content', :action => 'action', :id => o}, @defaults) - verify_generate('content/show/10', {}, {:controller => 'content', :action => 'show', :id => o}, @defaults) - end -end - -class RouteSetTests < Test::Unit::TestCase - def setup - @set = ActionController::Routing::RouteSet.new - @rails_route = ActionController::Routing::Route.new '/:controller/:action/:id', :action => 'index', :id => nil - @request = ActionController::TestRequest.new({}, {}, nil) - end - def test_emptyness - assert_equal true, @set.empty?, "New RouteSets should respond to empty? with true." - @set.each { flunk "New RouteSets should be empty." } - end - def test_add_illegal_route - assert_raises(TypeError) {@set.add_route "I'm not actually a route."} - end - def test_add_normal_route - @set.add_route @rails_route - seen = false - @set.each do |route| - assert_equal @rails_route, route - flunk("Each should have yielded only a single route!") if seen - seen = true - end + def test_all_static_no_requirements + c = [Static.new("hello"), Static.new("world")] + go c + + assert_equal "hello/world", execute({}, {}) end - def test_expand_controller_path_non_relative - defaults = {:controller => 'admin/user', :action => 'list'} - options = {:controller => '/content'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'content'}, options) - end - def test_expand_controller_path_relative_to_nested - defaults = {:controller => 'admin/user', :action => 'list'} - options = {:controller => 'access'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'admin/access'}, options) - end - def test_expand_controller_path_relative_to_root - defaults = {:controller => 'content', :action => 'list'} - options = {:controller => 'resource'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'resource'}, options) - end - def test_expand_controller_path_into_module - defaults = {:controller => 'content', :action => 'list'} - options = {:controller => 'admin/user'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'admin/user'}, options) - end - def test_expand_controller_path_switch_module_with_absolute - defaults = {:controller => 'user/news', :action => 'list'} - options = {:controller => '/admin/user'} - @set.expand_controller_path!(options, defaults) - assert_equal({:controller => 'admin/user'}, options) - end - def test_expand_controller_no_default - options = {:controller => 'content'} - @set.expand_controller_path!(options, {}) - assert_equal({:controller => 'content'}, options) + def test_basic_dynamic + c = [Static.new("hi"), Dynamic.new(:action)] + go c + + assert_equal 'hi/index', execute({:action => 'index'}, {:action => 'index'}) + assert_equal 'hi/show', execute({:action => 'show'}, {:action => 'index'}) + assert_equal 'hi/list+people', execute({}, {:action => 'list people'}) + assert_nil execute({},{}) end - # Don't put a leading / on the url. - # Make sure the controller is one from the above fake Controllers module. - def verify_recognize(expected_controller, expected_path_parameters=nil, path=nil) - @set.add_route(@rails_route) if @set.empty? - @request.path = path if path - controller = @set.recognize!(@request) - assert_equal expected_controller, controller - assert_equal expected_path_parameters, @request.path_parameters if expected_path_parameters + def test_dynamic_with_default + c = [Static.new("hi"), Dynamic.new(:action, :default => 'index')] + go c + + assert_equal 'hi', execute({:action => 'index'}, {:action => 'index'}) + assert_equal 'hi/show', execute({:action => 'show'}, {:action => 'index'}) + assert_equal 'hi/list+people', execute({}, {:action => 'list people'}) + assert_equal 'hi', execute({}, {}) end - # The expected url should not have a leading / - # You can use @defaults if you want a set of plausible defaults - def verify_generate(expected_url, options, expected_extras={}) - @set.add_route(@rails_route) if @set.empty? - components, extras = @set.generate(options, @request) - assert_equal expected_extras, extras, "#incorrect extra's" - assert_equal expected_url, components.join('/'), "incorrect url" + def test_dynamic_with_regexp_condition + c = [Static.new("hi"), Dynamic.new(:action, :condition => /^[a-z]+$/)] + go c + + assert_equal 'hi/index', execute({:action => 'index'}, {:action => 'index'}) + assert_nil execute({:action => 'fox5'}, {:action => 'index'}) + assert_nil execute({:action => 'something_is_up'}, {:action => 'index'}) + assert_nil execute({}, {:action => 'list people'}) + assert_equal 'hi/abunchofcharacter', execute({:action => 'abunchofcharacter'}, {}) + assert_nil execute({}, {}) end - def typical_request - @request.path_parameters = {:controller => 'content', :action => 'show', :id => '10'} + + def test_dynamic_with_default_and_regexp_condition + c = [Static.new("hi"), Dynamic.new(:action, :default => 'index', :condition => /^[a-z]+$/)] + go c + + assert_equal 'hi', execute({:action => 'index'}, {:action => 'index'}) + assert_nil execute({:action => 'fox5'}, {:action => 'index'}) + assert_nil execute({:action => 'something_is_up'}, {:action => 'index'}) + assert_nil execute({}, {:action => 'list people'}) + assert_equal 'hi/abunchofcharacter', execute({:action => 'abunchofcharacter'}, {}) + assert_equal 'hi', execute({}, {}) end - def typical_nested_request - @request.path_parameters = {:controller => 'admin/user', :action => 'grant', :id => '02seckar'} + + def test_path + c = [Static.new("hi"), Path.new(:file)] + go c + + assert_equal 'hi', execute({:file => []}, {}) + assert_equal 'hi/books/agile_rails_dev.pdf', execute({:file => %w(books agile_rails_dev.pdf)}, {}) + assert_equal 'hi/books/development%26whatever/agile_rails_dev.pdf', execute({:file => %w(books development&whatever agile_rails_dev.pdf)}, {}) + + assert_equal 'hi', execute({:file => ''}, {}) + assert_equal 'hi/books/agile_rails_dev.pdf', execute({:file => 'books/agile_rails_dev.pdf'}, {}) + assert_equal 'hi/books/development%26whatever/agile_rails_dev.pdf', execute({:file => 'books/development&whatever/agile_rails_dev.pdf'}, {}) end - def test_generate_typical_controller_action_path - typical_request - verify_generate('content/list', {:controller => 'content', :action => 'list'}) + def test_controller + c = [Static.new("hi"), Controller.new(:controller)] + go c + + assert_nil execute({}, {}) + assert_equal 'hi/content', execute({:controller => 'content'}, {}) + assert_equal 'hi/admin/user', execute({:controller => 'admin/user'}, {}) + assert_equal 'hi/content', execute({}, {:controller => 'content'}) + assert_equal 'hi/admin/user', execute({}, {:controller => 'admin/user'}) end - def test_generate_typical_controller_index_path_explicit_index - typical_request - verify_generate('content', {:controller => 'content', :action => 'index'}) + + def test_standard_route(time = ::RunTimeTests) + c = [Controller.new(:controller), Dynamic.new(:action, :default => 'index'), Dynamic.new(:id, :default => nil)] + go c + + # Make sure we get the right answers + assert_equal('content', execute({:action => 'index'}, {:controller => 'content', :action => 'list'})) + assert_equal('content/list', execute({:action => 'list'}, {:controller => 'content', :action => 'index'})) + assert_equal('content/show/10', execute({:action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'})) + + assert_equal('admin/user', execute({:action => 'index'}, {:controller => 'admin/user', :action => 'list'})) + assert_equal('admin/user/list', execute({:action => 'list'}, {:controller => 'admin/user', :action => 'index'})) + assert_equal('admin/user/show/10', execute({:action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'})) + + if time + GC.start + n = 1000 + time = Benchmark.realtime do n.times { + execute({:action => 'index'}, {:controller => 'content', :action => 'list'}) + execute({:action => 'list'}, {:controller => 'content', :action => 'index'}) + execute({:action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}) + + execute({:action => 'index'}, {:controller => 'admin/user', :action => 'list'}) + execute({:action => 'list'}, {:controller => 'admin/user', :action => 'index'}) + execute({:action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}) + } end + time -= Benchmark.realtime do n.times { } end + + puts "\n\nGeneration:" + per_url = time / (n * 6) + + puts "#{per_url * 1000} ms/url" + puts "#{1 / per_url} urls/s\n\n" + end end - def test_generate_typical_controller_index_path_explicit_index - typical_request - verify_generate('content', {:controller => 'content', :action => 'index'}) + + def test_default_route + g.if(g.check_conditions(:controller => 'content', :action => 'welcome')) { go [] } + + assert_nil execute({:controller => 'foo', :action => 'welcome'}, {}) + assert_nil execute({:controller => 'content', :action => 'elcome'}, {}) + assert_nil execute({:action => 'elcome'}, {:controller => 'content'}) + + assert_equal '', execute({:controller => 'content', :action => 'welcome'}, {}) + assert_equal '', execute({:action => 'welcome'}, {:controller => 'content'}) + assert_equal '', execute({:action => 'welcome', :id => '10'}, {:controller => 'content'}) end - def test_generate_typical_controller_index_path_implicit_index - typical_request - @request.path_parameters[:controller] = 'resource' - verify_generate('content', {:controller => 'content'}) +end + +class RouteTests < Test::Unit::TestCase + def route(*args) + @route = ::ActionController::Routing::Route.new(*args) unless args.empty? + return @route end - def test_generate_no_perfect_route - typical_request - verify_generate('admin/user/show/43seckar', {:controller => 'admin/user', :action => 'show', :id => '43seckar', :likes_fishing => 'fuzzy(0.3)'}, {:likes_fishing => 'fuzzy(0.3)'}) + def rec(path, show = false) + path = path.split('/') if path.is_a? String + index = 0 + source = route.write_recognition.to_s + puts "\n\n#{source}\n\n" if show + r = eval(source) + r ? r.symbolize_keys : r + end + def gen(options, recall = nil, show = false) + recall ||= options.dup + + expire_on = ::ActionController::Routing.expiry_hash(options, recall) + hash = merged = recall.merge(options) + not_expired = true + + source = route.write_generation.to_s + puts "\n\n#{source}\n\n" if show + eval(source) + end - def test_generate_no_match - @set.add_route(@rails_route) - @request.path_parameters = {} - assert_raises(ActionController::RoutingError) {@set.generate({}, @request)} + def test_static + route 'hello/world', :known => 'known_value' + + assert_nil rec('hello/turn') + assert_nil rec('turn/world') + assert_equal({:known => 'known_value'}, rec('hello/world')) + + assert_nil gen(:known => 'foo') + assert_nil gen({}) + assert_equal 'hello/world', gen(:known => 'known_value') + assert_equal 'hello/world', gen(:known => 'known_value', :extra => 'hi') + assert_equal [:extra], route.extra_keys(:known => 'known_value', :extra => 'hi') end - def test_encoded_strings - verify_recognize(Controllers::Admin::UserController, {:controller => 'admin/user', :action => 'info', :id => "Nicholas Seckar"}, path='/admin/user/info/Nicholas%20Seckar') + def test_dynamic + route 'hello/:name', :controller => 'content', :action => 'show_person' + + assert_nil rec('hello') + assert_nil rec('foo/bar') + assert_equal({:controller => ::Controllers::ContentController, :action => 'show_person', :name => 'rails'}, rec('hello/rails')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'show_person', :name => 'Nicholas Seckar'}, rec('hello/Nicholas+Seckar')) + + assert_nil gen(:controller => 'content', :action => 'show_dude', :name => 'rails') + assert_nil gen(:controller => 'content', :action => 'show_person') + assert_nil gen(:controller => 'admin/user', :action => 'show_person', :name => 'rails') + assert_equal 'hello/rails', gen(:controller => 'content', :action => 'show_person', :name => 'rails') + assert_equal 'hello/Nicholas+Seckar', gen(:controller => 'content', :action => 'show_person', :name => 'Nicholas Seckar') end - def test_action_dropped_when_controller_changes - @request.path_parameters = {:controller => 'content', :action => 'list'} - options = {:controller => 'resource'} - @set.connect ':action/:controller' - verify_generate('index/resource', options) + def test_typical + route ':controller/:action/:id', :action => 'index', :id => nil + assert_nil rec('hello') + assert_nil rec('foo bar') + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}, rec('content')) + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'index'}, rec('admin/user')) + + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'index'}, rec('admin/user/index')) + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'list'}, rec('admin/user/list')) + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'show', :id => '10'}, rec('admin/user/show/10')) + + assert_equal({:controller => ::Controllers::ContentController, :action => 'list'}, rec('content/list')) + assert_equal({:controller => ::Controllers::ContentController, :action => 'show', :id => '10'}, rec('content/show/10')) + + + assert_equal 'content', gen(:controller => 'content', :action => 'index') + assert_equal 'content/list', gen(:controller => 'content', :action => 'list') + assert_equal 'content/show/10', gen(:controller => 'content', :action => 'show', :id => '10') + + assert_equal 'admin/user', gen(:controller => 'admin/user', :action => 'index') + assert_equal 'admin/user', gen(:controller => 'admin/user') + assert_equal 'admin/user', gen({:controller => 'admin/user'}, {:controller => 'content', :action => 'list', :id => '10'}) + assert_equal 'admin/user/show/10', gen(:controller => 'admin/user', :action => 'show', :id => '10') end +end - def test_action_dropped_when_controller_given - @request.path_parameters = {:controller => 'content', :action => 'list'} - options = {:controller => 'content'} - @set.connect ':action/:controller' - verify_generate('index/content', options) +class RouteSetTests < Test::Unit::TestCase + attr_reader :rs + def setup + @rs = ::ActionController::Routing::RouteSet.new + @rs.draw {|m| m.connect ':controller/:action/:id' } end - def test_default_dropped_with_nil_option - @request.path_parameters = {:controller => 'content', :action => 'action', :id => '10'} - verify_generate 'content/action', {:id => nil} - end - - def test_url_to_self - @request.path_parameters = {:controller => 'admin/users', :action => 'index'} - verify_generate 'admin/users', {} + def test_default_setup + assert_equal({:controller => ::Controllers::ContentController, :action => 'index'}.stringify_keys, rs.recognize_path(%w(content))) + assert_equal({:controller => ::Controllers::ContentController, :action => 'list'}.stringify_keys, rs.recognize_path(%w(content list))) + assert_equal({:controller => ::Controllers::ContentController, :action => 'show', :id => '10'}.stringify_keys, rs.recognize_path(%w(content show 10))) + + assert_equal({:controller => ::Controllers::Admin::UserController, :action => 'show', :id => '10'}.stringify_keys, rs.recognize_path(%w(admin user show 10))) + + assert_equal ['admin/user/show/10', {}], rs.generate({:controller => 'admin/user', :action => 'show', :id => 10}) + + assert_equal ['admin/user/show', {}], rs.generate({:action => 'show'}, {:controller => 'admin/user', :action => 'list', :id => '10'}) + assert_equal ['admin/user/list/10', {}], rs.generate({}, {:controller => 'admin/user', :action => 'list', :id => '10'}) end - - def test_url_with_spaces_in_controller - @request.path = 'not%20a%20valid/controller/name' - @set.add_route(@rails_route) if @set.empty? - assert_raises(ActionController::RoutingError) {@set.recognize!(@request)} + + def test_time_recognition + n = 10000 + if RunTimeTests + GC.start + rectime = Benchmark.realtime do + n.times do + rs.recognize_path(%w(content)) + rs.recognize_path(%w(content list)) + rs.recognize_path(%w(content show 10)) + rs.recognize_path(%w(admin user)) + rs.recognize_path(%w(admin user list)) + rs.recognize_path(%w(admin user show 10)) + end + end + puts "\n\nRecognition (RouteSet):" + per_url = rectime / (n * 6) + puts "#{per_url * 1000} ms/url" + puts "#{1 / per_url} url/s\n\n" + end end - def test_url_with_dots_in_controller - @request.path = 'not.valid/controller/name' - @set.add_route(@rails_route) if @set.empty? - assert_raises(ActionController::RoutingError) {@set.recognize!(@request)} + def test_time_generation + n = 5000 + if RunTimeTests + GC.start + pairs = [ + [{:controller => 'content', :action => 'index'}, {:controller => 'content', :action => 'show'}], + [{:controller => 'content'}, {:controller => 'content', :action => 'index'}], + [{:controller => 'content', :action => 'list'}, {:controller => 'content', :action => 'index'}], + [{:controller => 'content', :action => 'show', :id => '10'}, {:controller => 'content', :action => 'list'}], + [{:controller => 'admin/user', :action => 'index'}, {:controller => 'admin/user', :action => 'show'}], + [{:controller => 'admin/user'}, {:controller => 'admin/user', :action => 'index'}], + [{:controller => 'admin/user', :action => 'list'}, {:controller => 'admin/user', :action => 'index'}], + [{:controller => 'admin/user', :action => 'show', :id => '10'}, {:controller => 'admin/user', :action => 'list'}], + ] + p = nil + gentime = Benchmark.realtime do + n.times do + pairs.each {|(a, b)| rs.generate(a, b)} + end + end + + puts "\n\nGeneration (RouteSet): (#{(n * 8)} urls)" + per_url = gentime / (n * 8) + puts "#{per_url * 1000} ms/url" + puts "#{1 / per_url} url/s\n\n" + end end - def test_generate_of_empty_url - @set.connect '', :controller => 'content', :action => 'view', :id => "1" - @set.add_route(@rails_route) - verify_generate('content/view/2', {:controller => 'content', :action => 'view', :id => 2}) - verify_generate('', {:controller => 'content', :action => 'view', :id => 1}) + def test_basic_named_route + rs.home '', :controller => 'content', :action => 'list' + x = setup_for_named_route + assert_equal({:controller => 'content', :action => 'list'}, + x.new.send(:home_url)) end - def test_generate_of_empty_url_with_numeric_requirement - @set.connect '', :controller => 'content', :action => 'view', :id => 1 - @set.add_route(@rails_route) - verify_generate('content/view/2', {:controller => 'content', :action => 'view', :id => 2}) - verify_generate('', {:controller => 'content', :action => 'view', :id => 1}) + + def test_named_route_with_option + rs.page 'page/:title', :controller => 'content', :action => 'show_page' + x = setup_for_named_route + assert_equal({:controller => 'content', :action => 'show_page', :title => 'new stuff'}, + x.new.send(:page_url, :title => 'new stuff')) + end + + def setup_for_named_route + x = Class.new + x.send(:define_method, :url_for) {|x| x} + x.send :include, ::ActionController::Routing::NamedRoutes + x end end -#require '../assertions/action_pack_assertions.rb' -class AssertionRoutingTests < Test::Unit::TestCase - def test_assert_routing - ActionController::Routing::Routes.reload rescue nil - assert_routing('content', {:controller => 'content', :action => 'index'}) - end end -- cgit v1.2.3