Skip to content

Commit

Permalink
Routes refactoring:
Browse files Browse the repository at this point in the history
* added more tests for prefix generation
* fixed bug with generating host for both prefix and url
* refactored url_for method
* organized tests for prefix generation
  • Loading branch information
drogus committed Sep 3, 2010
1 parent 229a868 commit e9791be
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 60 deletions.
3 changes: 1 addition & 2 deletions actionpack/lib/action_dispatch/routing/mapper.rb
Expand Up @@ -288,8 +288,7 @@ def define_generate_prefix(app, name)
_router = @set _router = @set
app.routes.class_eval do app.routes.class_eval do
define_method :_generate_prefix do |options| define_method :_generate_prefix do |options|
keys = _route.segment_keys + ActionDispatch::Routing::RouteSet::RESERVED_OPTIONS prefix_options = options.slice(*_route.segment_keys)
prefix_options = options.slice(*keys)
# we must actually delete prefix segment keys to avoid passing them to next url_for # we must actually delete prefix segment keys to avoid passing them to next url_for
_route.segment_keys.each { |k| options.delete(k) } _route.segment_keys.each { |k| options.delete(k) }
_router.url_helpers.send("#{name}_path", prefix_options) _router.url_helpers.send("#{name}_path", prefix_options)
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/routing/route_set.rb
Expand Up @@ -452,7 +452,7 @@ def generate(options, recall = {}, extras = false)
Generator.new(options, recall, self, extras).generate Generator.new(options, recall, self, extras).generate
end end


RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :script_name, :routes] RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :script_name]


def _generate_prefix(options = {}) def _generate_prefix(options = {})
nil nil
Expand Down
10 changes: 4 additions & 6 deletions actionpack/lib/action_dispatch/routing/url_for.rb
Expand Up @@ -123,19 +123,17 @@ def url_options
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok' # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
# url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/' # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33' # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
def url_for(*args) def url_for(options = nil, *args)
if args.first.respond_to?(:routes) if options.respond_to?(:routes)
app = args.shift _with_routes(options.routes) do
_with_routes(app.routes) do
if args.first.is_a? Symbol if args.first.is_a? Symbol
named_route = args.shift named_route = args.shift
url_for _routes.url_helpers.__send__("hash_for_#{named_route}", *args) url_for _routes.url_helpers.send("hash_for_#{named_route}", *args)
else else
url_for(*args) url_for(*args)
end end
end end
else else
options = args.first
case options case options
when String when String
options options
Expand Down
117 changes: 71 additions & 46 deletions actionpack/test/dispatch/prefix_generation_test.rb
Expand Up @@ -10,7 +10,8 @@ def self.routes
@routes ||= begin @routes ||= begin
routes = ActionDispatch::Routing::RouteSet.new routes = ActionDispatch::Routing::RouteSet.new
routes.draw do routes.draw do
match "/posts/:id", :to => "inside_engine_generating#index", :as => :post match "/posts/:id", :to => "inside_engine_generating#show", :as => :post
match "/posts", :to => "inside_engine_generating#index", :as => :posts
match "/url_to_application", :to => "inside_engine_generating#url_to_application" match "/url_to_application", :to => "inside_engine_generating#url_to_application"
end end


Expand Down Expand Up @@ -47,114 +48,138 @@ def self.call(env)
end end


class ::InsideEngineGeneratingController < ActionController::Base class ::InsideEngineGeneratingController < ActionController::Base
include BlogEngine.routes.url_helpers

def index def index
render :text => url_for(BlogEngine, :post_path, :id => params[:id]) render :text => posts_path
end

def show
render :text => post_path(:id => params[:id])
end end


def url_to_application def url_to_application
path = url_for( :routes => RailsApplication.routes, path = url_for( RailsApplication,
:controller => "outside_engine_generating", :controller => "outside_engine_generating",
:action => "index", :action => "index",
:only_path => true) :only_path => true)
render :text => path render :text => path
end end
end end


class ::OutsideEngineGeneratingController < ActionController::Base class ::OutsideEngineGeneratingController < ActionController::Base
include BlogEngine.routes.url_helpers
def index def index
render :text => url_for(BlogEngine, :post_path, :id => 1) render :text => url_for(BlogEngine, :post_path, :id => 1)
end end
end end


class Foo class EngineObject
include ActionDispatch::Routing::UrlFor include ActionDispatch::Routing::UrlFor
include BlogEngine.routes.url_helpers include BlogEngine.routes.url_helpers

def foo
post_path(42)
end
end end


class Bar class AppObject
include ActionDispatch::Routing::UrlFor include ActionDispatch::Routing::UrlFor
include RailsApplication.routes.url_helpers include RailsApplication.routes.url_helpers

def bar
root_path
end
end end


RailsApplication.routes # force draw # force draw
include BlogEngine.routes.url_helpers RailsApplication.routes


def app def app
RailsApplication RailsApplication
end end


def engine_object
@engine_object ||= EngineObject.new
end

def app_object
@app_object ||= AppObject.new
end

def setup def setup
RailsApplication.routes.default_url_options = {} RailsApplication.routes.default_url_options = {}
end end


test "generating URL with prefix" do # Inside Engine
assert_equal "/awesome/blog/posts/1", post_path(:id => 1) test "[ENGINE] generating engine's url use SCRIPT_NAME from request" do
get "/pure-awesomeness/blog/posts/1"
assert_equal "/pure-awesomeness/blog/posts/1", last_response.body
end end


test "use SCRIPT_NAME inside the engine" do test "[ENGINE] generating application's url never uses SCRIPT_NAME from request" do
get "/pure-awesomness/blog/posts/1" get "/pure-awesomeness/blog/url_to_application"
assert_equal "/pure-awesomness/blog/posts/1", last_response.body assert_equal "/generate", last_response.body
end end


test "prepend prefix outside the engine" do test "[ENGINE] generating application's url includes default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/pure-awesomeness/blog/url_to_application"
assert_equal "/something/generate", last_response.body
end

test "[ENGINE] generating application's url should give higher priority to default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/pure-awesomeness/blog/url_to_application", {}, 'SCRIPT_NAME' => '/foo'
assert_equal "/something/generate", last_response.body
end

# Inside Application
test "[APP] generating engine's route includes prefix" do
get "/generate" get "/generate"
assert_equal "/awesome/blog/posts/1", last_response.body assert_equal "/awesome/blog/posts/1", last_response.body
end end


test "prepend prefix outside the engine and use default_url_options[:script_name]" do test "[APP] generating engine's route includes default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"} RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/generate" get "/generate"
assert_equal "/something/awesome/blog/posts/1", last_response.body assert_equal "/something/awesome/blog/posts/1", last_response.body
end end


test "give higher priority to default_url_options[:script_name]" do test "[APP] generating engine's route should give higher priority to default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"} RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/generate", {}, 'SCRIPT_NAME' => "/foo" get "/generate", {}, 'SCRIPT_NAME' => "/foo"
assert_equal "/something/awesome/blog/posts/1", last_response.body assert_equal "/something/awesome/blog/posts/1", last_response.body
end end


test "generating urls with options for prefix and named_route" do # Inside any Object
assert_equal "/pure-awesomness/blog/posts/3", post_path(:id => 3, :omg => "pure-awesomness") test "[OBJECT] generating engine's route includes prefix" do
assert_equal "/awesome/blog/posts/1", engine_object.post_path(:id => 1)
end end


test "generating urls with url_for should prepend the prefix" do test "[OBJECT] generating engine's route includes dynamic prefix" do
path = BlogEngine.routes.url_for(:omg => 'omg', :controller => "inside_engine_generating", :action => "index", :id => 1, :only_path => true) assert_equal "/pure-awesomeness/blog/posts/3", engine_object.post_path(:id => 3, :omg => "pure-awesomeness")
assert_equal "/omg/blog/posts/1", path
end end


test "generating urls from a regular class" do test "[OBJECT] generating engine's route includes default_url_options[:script_name]" do
assert_equal "/awesome/blog/posts/42", Foo.new.foo RailsApplication.routes.default_url_options = {:script_name => "/something"}
assert_equal "/something/pure-awesomeness/blog/posts/3", engine_object.post_path(:id => 3, :omg => "pure-awesomeness")
end end


test "generating application's url from engine" do test "[OBJECT] generating application's route" do
get "/pure-awesomness/blog/url_to_application" assert_equal "/", app_object.root_path
assert_equal "/generate", last_response.body
end end


test "generating application's url from engine with default_url_options[:script_name]" do test "[OBJECT] generating application's route includes default_url_options[:script_name]" do
RailsApplication.routes.default_url_options = {:script_name => "/something"} RailsApplication.routes.default_url_options = {:script_name => "/something"}
get "/pure-awesomness/blog/url_to_application" assert_equal "/something/", app_object.root_path
assert_equal "/something/generate", last_response.body
end end


test "generating application's url from engine should give higher priority to default_url_options[:script_name]" do test "[OBJECT] generating engine's route with url_for" do
RailsApplication.routes.default_url_options = {:script_name => "/something"} path = engine_object.url_for(BlogEngine,
get "/pure-awesomness/blog/url_to_application", {}, 'SCRIPT_NAME' => '/foo' :controller => "inside_engine_generating",
assert_equal "/something/generate", last_response.body :action => "show",
end :only_path => true,
:omg => "omg",
:id => 1)
assert_equal "/omg/blog/posts/1", path


test "using default_url_options[:script_name] in regular classes" do path = engine_object.url_for(BlogEngine, :posts_path)
RailsApplication.routes.default_url_options = {:script_name => "/something"} assert_equal "/awesome/blog/posts", path
assert_equal "/something/", Bar.new.bar
path = engine_object.url_for(BlogEngine, :posts_url, :host => "example.com")
assert_equal "http://example.com/awesome/blog/posts", path
end end
end end
end end
Expand Up @@ -50,10 +50,10 @@ def index
end end
def generate_application_route def generate_application_route
path = url_for( :routes => Rails.application.routes, path = url_for(Rails.application,
:controller => "main", :controller => "main",
:action => "index", :action => "index",
:only_path => true) :only_path => true)
render :text => path render :text => path
end end
end end
Expand All @@ -66,7 +66,7 @@ def engine_route
end end
def url_for_engine_route def url_for_engine_route
render :text => url_for(:controller => "posts", :action => "index", :user => "john", :only_path => true, :routes => Blog::Engine.routes) render :text => url_for(Blog::Engine, :controller => "posts", :action => "index", :user => "john", :only_path => true)
end end
end end
RUBY RUBY
Expand Down Expand Up @@ -110,6 +110,7 @@ def script_name(script_name)
script_name "/foo" script_name "/foo"
get "/engine_route", {}, 'SCRIPT_NAME' => "/foo" get "/engine_route", {}, 'SCRIPT_NAME' => "/foo"
assert_equal "/foo/anonymous/blog/posts", last_response.body assert_equal "/foo/anonymous/blog/posts", last_response.body

script_name "/foo" script_name "/foo"
get "/url_for_engine_route", {}, 'SCRIPT_NAME' => "/foo" get "/url_for_engine_route", {}, 'SCRIPT_NAME' => "/foo"
assert_equal "/foo/john/blog/posts", last_response.body assert_equal "/foo/john/blog/posts", last_response.body
Expand Down

0 comments on commit e9791be

Please sign in to comment.