diff options
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 21 | ||||
-rw-r--r-- | actionpack/test/abstract_unit.rb | 15 | ||||
-rw-r--r-- | actionpack/test/controller/routing_test.rb | 67 | ||||
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 2 | ||||
-rw-r--r-- | activesupport/test/callbacks_test.rb | 56 |
6 files changed, 156 insertions, 10 deletions
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 20077befca..e2d7a29079 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -55,6 +55,7 @@ module ActionDispatch def initialize(set, scope, path, options) @set, @scope = set, scope + @segment_keys = nil @options = (@scope[:options] || {}).merge(options) @path = normalize_path(path) normalize_options! @@ -214,7 +215,9 @@ module ActionDispatch end def segment_keys - @segment_keys ||= Journey::Path::Pattern.new( + return @segment_keys if @segment_keys + + @segment_keys = Journey::Path::Pattern.new( Journey::Router::Strexp.compile(@path, requirements, SEPARATORS) ).names end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 2c21887220..6100e69d4b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -360,7 +360,26 @@ module ActionDispatch SEPARATORS, anchor) - Journey::Path::Pattern.new(strexp) + pattern = Journey::Path::Pattern.new(strexp) + + builder = Journey::GTG::Builder.new pattern.spec + + # Get all the symbol nodes followed by literals that are not the + # dummy node. + symbols = pattern.spec.grep(Journey::Nodes::Symbol).find_all { |n| + builder.followpos(n).first.literal? + } + + # Get all the symbol nodes preceded by literals. + symbols.concat pattern.spec.find_all(&:literal?).map { |n| + builder.followpos(n).first + }.find_all(&:symbol?) + + symbols.each { |x| + x.regexp = /(?:#{Regexp.union(x.regexp, '-')})+/ + } + + pattern end private :build_path diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 0a25d7ba47..b1a5356ddd 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -344,6 +344,21 @@ module ActionDispatch end end +module ActionDispatch + module RoutingVerbs + def get(uri_or_host, path = nil, port = nil) + host = uri_or_host.host unless path + path ||= uri_or_host.path + + params = {'PATH_INFO' => path, + 'REQUEST_METHOD' => 'GET', + 'HTTP_HOST' => host} + + routes.call(params)[2].join + end + end +end + module RoutingTestHelpers def url_for(set, options, recall = nil) set.send(:url_for, options.merge(:only_path => true, :_path_segments => recall)) diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index bec9eb16f3..9a0cfc8e8e 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -73,23 +73,76 @@ end class LegacyRouteSetTests < ActiveSupport::TestCase include RoutingTestHelpers + include ActionDispatch::RoutingVerbs attr_reader :rs + alias :routes :rs def setup @rs = ::ActionDispatch::Routing::RouteSet.new @response = nil end - def get(uri_or_host, path = nil, port = nil) - host = uri_or_host.host unless path - path ||= uri_or_host.path + def test_symbols_with_dashes + rs.draw do + match '/:artist/:song-omg', :to => lambda { |env| + resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + [200, {}, [resp]] + } + end + + hash = JSON.load get(URI('http://example.org/journey/faithfully-omg')) + assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash) + end + + def test_id_with_dash + rs.draw do + match '/journey/:id', :to => lambda { |env| + resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + [200, {}, [resp]] + } + end + + hash = JSON.load get(URI('http://example.org/journey/faithfully-omg')) + assert_equal({"id"=>"faithfully-omg"}, hash) + end + + def test_dash_with_custom_regexp + rs.draw do + match '/:artist/:song-omg', :constraints => { :song => /\d+/ }, :to => lambda { |env| + resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + [200, {}, [resp]] + } + end + + hash = JSON.load get(URI('http://example.org/journey/123-omg')) + assert_equal({"artist"=>"journey", "song"=>"123"}, hash) + assert_equal 'Not Found', get(URI('http://example.org/journey/faithfully-omg')) + end - params = {'PATH_INFO' => path, - 'REQUEST_METHOD' => 'GET', - 'HTTP_HOST' => host} + def test_pre_dash + rs.draw do + match '/:artist/omg-:song', :to => lambda { |env| + resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + [200, {}, [resp]] + } + end + + hash = JSON.load get(URI('http://example.org/journey/omg-faithfully')) + assert_equal({"artist"=>"journey", "song"=>"faithfully"}, hash) + end + + def test_pre_dash_with_custom_regexp + rs.draw do + match '/:artist/omg-:song', :constraints => { :song => /\d+/ }, :to => lambda { |env| + resp = JSON.dump env[ActionDispatch::Routing::RouteSet::PARAMETERS_KEY] + [200, {}, [resp]] + } + end - @rs.call(params)[2].join + hash = JSON.load get(URI('http://example.org/journey/omg-123')) + assert_equal({"artist"=>"journey", "song"=>"123"}, hash) + assert_equal 'Not Found', get(URI('http://example.org/journey/omg-faithfully')) end def test_regexp_precidence diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 9cea09db41..5eaeac2cb3 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -359,7 +359,7 @@ module ActiveSupport def __run_callbacks(key, kind, object, &blk) #:nodoc: name = __callback_runner_name(kind) unless object.respond_to?(name) - str = send("_#{kind}_callbacks").compile(key, object) + str = object.send("_#{kind}_callbacks").compile(key, object) class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 def #{name}() #{str} end protected :#{name} diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index 2c2a420619..032787f0f4 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -344,6 +344,54 @@ module CallbacksTest end end + module ExtendModule + def self.extended(base) + base.class_eval do + set_callback :save, :before, :record3 + end + end + def record3 + @recorder << 3 + end + end + + module IncludeModule + def self.included(base) + base.class_eval do + set_callback :save, :before, :record2 + end + end + def record2 + @recorder << 2 + end + end + + class ExtendCallbacks + + include ActiveSupport::Callbacks + + define_callbacks :save + set_callback :save, :before, :record1 + + include IncludeModule + + def save + run_callbacks :save + end + + attr_reader :recorder + + def initialize + @recorder = [] + end + + private + + def record1 + @recorder << 1 + end + end + class AroundCallbacksTest < ActiveSupport::TestCase def test_save_around around = AroundPerson.new @@ -645,4 +693,12 @@ module CallbacksTest end end + class ExtendCallbacksTest < ActiveSupport::TestCase + def test_save + model = ExtendCallbacks.new.extend ExtendModule + model.save + assert_equal [1, 2, 3], model.recorder + end + end + end |