diff options
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 16 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing_test.rb | 33 | ||||
-rw-r--r-- | railties/test/application/routing_test.rb | 28 |
3 files changed, 73 insertions, 4 deletions
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 835ba03784..7ac07fe426 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -217,27 +217,35 @@ module ActionDispatch self.valid_conditions.delete(:id) self.valid_conditions.push(:controller, :action) + @append = [] @disable_clear_and_finalize = false clear! end def draw(&block) clear! unless @disable_clear_and_finalize + eval_block(block) + finalize! unless @disable_clear_and_finalize + + nil + end + + def append(&block) + @append << block + end + def eval_block(block) mapper = Mapper.new(self) if default_scope mapper.with_default_scope(default_scope, &block) else mapper.instance_exec(&block) end - - finalize! unless @disable_clear_and_finalize - - nil end def finalize! return if @finalized + @append.each { |blk| eval_block(blk) } @finalized = true @set.freeze end diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index b642adc06b..8a2311ab3e 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -2152,6 +2152,39 @@ private end end +class TestAppendingRoutes < ActionController::IntegrationTest + def simple_app(resp) + lambda { |e| [ 200, { 'Content-Type' => 'text/plain' }, [resp] ] } + end + + setup do + s = self + @app = ActionDispatch::Routing::RouteSet.new + @app.append do + match '/hello' => s.simple_app('fail') + match '/goodbye' => s.simple_app('goodbye') + end + + @app.draw do + match '/hello' => s.simple_app('hello') + end + end + + def test_goodbye_should_be_available + get '/goodbye' + assert_equal 'goodbye', @response.body + end + + def test_hello_should_not_be_overwritten + get '/hello' + assert_equal 'hello', @response.body + end + + def test_missing_routes_are_still_missing + get '/random' + assert_equal 404, @response.status + end +end class TestDefaultScope < ActionController::IntegrationTest module ::Blog diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index bf2af11e9f..42ee4c5ebc 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -177,6 +177,34 @@ module ApplicationTests assert_equal 'admin::foo', last_response.body end + test "reloads appended route blocks" do + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do + match ':controller#:action' + end + RUBY + + add_to_config <<-R + routes.append do + match '/win' => lambda { |e| [200, {'Content-Type'=>'text/plain'}, 'WIN'] } + end + R + + app 'development' + + get '/win' + assert_equal 'WIN', last_response.body + + app_file 'config/routes.rb', <<-R + AppTemplate::Application.routes.draw do + match 'lol' => 'hello#index' + end + R + + get '/win' + assert_equal 'WIN', last_response.body + end + {"development" => "baz", "production" => "bar"}.each do |mode, expected| test "reloads routes when configuration is changed in #{mode}" do controller :foo, <<-RUBY |