Merge branch 'master' into testing

This commit is contained in:
Jeremy Kemper
2008-11-11 10:22:09 -08:00
7 changed files with 69 additions and 42 deletions

View File

@@ -1,23 +1,16 @@
module ActionController
module Routing
class RouteBuilder #:nodoc:
attr_accessor :separators, :optional_separators
attr_reader :separators, :optional_separators
attr_reader :separator_regexp, :nonseparator_regexp, :interval_regexp
def initialize
self.separators = Routing::SEPARATORS
self.optional_separators = %w( / )
end
@separators = Routing::SEPARATORS
@optional_separators = %w( / )
def separator_pattern(inverted = false)
"[#{'^' if inverted}#{Regexp.escape(separators.join)}]"
end
def interval_regexp
Regexp.new "(.*?)(#{separators.source}|$)"
end
def multiline_regexp?(expression)
expression.options & Regexp::MULTILINE == Regexp::MULTILINE
@separator_regexp = /[#{Regexp.escape(separators.join)}]/
@nonseparator_regexp = /\A([^#{Regexp.escape(separators.join)}]+)/
@interval_regexp = /(.*?)(#{separator_regexp}|$)/
end
# Accepts a "route path" (a string defining a route), and returns the array
@@ -30,7 +23,7 @@ module ActionController
rest, segments = path, []
until rest.empty?
segment, rest = segment_for rest
segment, rest = segment_for(rest)
segments << segment
end
segments
@@ -39,20 +32,20 @@ module ActionController
# A factory method that returns a new segment instance appropriate for the
# format of the given string.
def segment_for(string)
segment = case string
when /\A:(\w+)/
key = $1.to_sym
case key
when :controller then ControllerSegment.new(key)
else DynamicSegment.new key
end
when /\A\*(\w+)/ then PathSegment.new($1.to_sym, :optional => true)
when /\A\?(.*?)\?/
StaticSegment.new($1, :optional => true)
when /\A(#{separator_pattern(:inverted)}+)/ then StaticSegment.new($1)
when Regexp.new(separator_pattern) then
DividerSegment.new($&, :optional => (optional_separators.include? $&))
end
segment =
case string
when /\A:(\w+)/
key = $1.to_sym
key == :controller ? ControllerSegment.new(key) : DynamicSegment.new(key)
when /\A\*(\w+)/
PathSegment.new($1.to_sym, :optional => true)
when /\A\?(.*?)\?/
StaticSegment.new($1, :optional => true)
when nonseparator_regexp
StaticSegment.new($1)
when separator_regexp
DividerSegment.new($&, :optional => optional_separators.include?($&))
end
[segment, $~.post_match]
end
@@ -98,7 +91,7 @@ module ActionController
if requirement.source =~ %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
end
if multiline_regexp?(requirement)
if requirement.multiline?
raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
end
segment.regexp = requirement

View File

@@ -219,7 +219,7 @@ module ActionController
next_capture = 1
extraction = segments.collect do |segment|
x = segment.match_extraction(next_capture)
next_capture += Regexp.new(segment.regexp_chunk).number_of_captures
next_capture += segment.number_of_captures
x
end
extraction.compact

View File

@@ -27,6 +27,10 @@ class Regexp #:nodoc:
Regexp.new("|#{source}").match('').captures.length
end
def multiline?
options & MULTILINE == MULTILINE
end
class << self
def optionalize(pattern)
case unoptionalize(pattern)

View File

@@ -13,6 +13,10 @@ module ActionController
@is_optional = false
end
def number_of_captures
Regexp.new(regexp_chunk).number_of_captures
end
def extraction_code
nil
end
@@ -84,6 +88,10 @@ module ActionController
optional? ? Regexp.optionalize(chunk) : chunk
end
def number_of_captures
0
end
def build_pattern(pattern)
escaped = Regexp.escape(value)
if optional? && ! pattern.empty?
@@ -194,10 +202,16 @@ module ActionController
end
end
def number_of_captures
if regexp
regexp.number_of_captures + 1
else
1
end
end
def build_pattern(pattern)
chunk = regexp_chunk
chunk = "(#{chunk})" if Regexp.new(chunk).number_of_captures == 0
pattern = "#{chunk}#{pattern}"
pattern = "#{regexp_chunk}#{pattern}"
optional? ? Regexp.optionalize(pattern) : pattern
end
@@ -230,6 +244,10 @@ module ActionController
"(?i-:(#{(regexp || Regexp.union(*possible_names)).source}))"
end
def number_of_captures
1
end
# Don't URI.escape the controller name since it may contain slashes.
def interpolation_chunk(value_code = local_name)
"\#{#{value_code}.to_s}"
@@ -275,6 +293,10 @@ module ActionController
regexp || "(.*)"
end
def number_of_captures
regexp ? regexp.number_of_captures : 1
end
def optionality_implied?
true
end

View File

@@ -286,7 +286,7 @@ module ActiveRecord
case operation
when 'count' then value.to_i
when 'sum' then type_cast_using_column(value || '0', column)
when 'avg' then value && value.to_f.to_d
when 'avg' then value && (value == 0 ? 0.0.to_d : value.to_d)
else type_cast_using_column(value, column)
end
end

View File

@@ -138,14 +138,22 @@ module ActiveSupport #:nodoc:
end
def load_with_new_constant_marking(file, *extras) #:nodoc:
Dependencies.new_constants_in(Object) { load_without_new_constant_marking(file, *extras) }
if Dependencies.load?
Dependencies.new_constants_in(Object) { load_without_new_constant_marking(file, *extras) }
else
load_without_new_constant_marking(file, *extras)
end
rescue Exception => exception # errors from loading file
exception.blame_file! file
raise
end
def require(file, *extras) #:nodoc:
Dependencies.new_constants_in(Object) { super }
if Dependencies.load?
Dependencies.new_constants_in(Object) { super }
else
super
end
rescue Exception => exception # errors from required file
exception.blame_file! file
raise

View File

@@ -694,17 +694,17 @@ class DependenciesTest < Test::Unit::TestCase
with_loading 'autoloading_fixtures' do
ActiveSupport::Dependencies.mechanism = :require
2.times do
assert_raise(NameError) {"RaisesNameError".constantize}
assert_raise(NameError) { assert_equal 123, ::RaisesNameError::FooBarBaz }
end
end
end
def test_autoload_doesnt_shadow_name_error
with_loading 'autoloading_fixtures' do
assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it hasn't been referenced yet!"
Object.send(:remove_const, :RaisesNameError) if defined?(::RaisesNameError)
2.times do
begin
::RaisesNameError.object_id
::RaisesNameError::FooBarBaz.object_id
flunk 'should have raised NameError when autoloaded file referenced FooBarBaz'
rescue NameError => e
assert_equal 'uninitialized constant RaisesNameError::FooBarBaz', e.message
@@ -712,9 +712,9 @@ class DependenciesTest < Test::Unit::TestCase
assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
end
assert !defined?(RaisesNameError)
assert !defined?(::RaisesNameError)
2.times do
assert_raise(NameError) { RaisesNameError }
assert_raise(NameError) { ::RaisesNameError }
assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
end
end