activesupport 3.0.0.beta → 3.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (73) hide show
  1. data/CHANGELOG +15 -1
  2. data/lib/active_support.rb +3 -0
  3. data/lib/active_support/all.rb +0 -1
  4. data/lib/active_support/cache/mem_cache_store.rb +1 -1
  5. data/lib/active_support/callbacks.rb +2 -2
  6. data/lib/active_support/core_ext/array/conversions.rb +0 -1
  7. data/lib/active_support/core_ext/array/extract_options.rb +16 -1
  8. data/lib/active_support/core_ext/class.rb +1 -0
  9. data/lib/active_support/core_ext/class/attribute.rb +30 -5
  10. data/lib/active_support/core_ext/class/attribute_accessors.rb +33 -27
  11. data/lib/active_support/core_ext/class/delegating_attributes.rb +10 -7
  12. data/lib/active_support/core_ext/class/subclasses.rb +55 -0
  13. data/lib/active_support/core_ext/date_time/conversions.rb +1 -0
  14. data/lib/active_support/core_ext/file/atomic.rb +3 -2
  15. data/lib/active_support/core_ext/file/path.rb +5 -0
  16. data/lib/active_support/core_ext/hash/conversions.rb +9 -0
  17. data/lib/active_support/core_ext/kernel.rb +0 -1
  18. data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
  19. data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
  20. data/lib/active_support/core_ext/module.rb +5 -3
  21. data/lib/active_support/core_ext/module/anonymous.rb +24 -0
  22. data/lib/active_support/core_ext/module/attribute_accessors.rb +25 -21
  23. data/lib/active_support/core_ext/module/delegation.rb +20 -9
  24. data/lib/active_support/core_ext/module/introspection.rb +8 -8
  25. data/lib/active_support/core_ext/module/method_names.rb +14 -0
  26. data/lib/active_support/core_ext/module/reachable.rb +10 -0
  27. data/lib/active_support/core_ext/module/remove_method.rb +6 -0
  28. data/lib/active_support/core_ext/object.rb +7 -1
  29. data/lib/active_support/core_ext/object/extending.rb +11 -0
  30. data/lib/active_support/core_ext/object/singleton_class.rb +13 -0
  31. data/lib/active_support/core_ext/proc.rb +3 -3
  32. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  33. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  34. data/lib/active_support/core_ext/string/interpolation.rb +1 -91
  35. data/lib/active_support/core_ext/string/output_safety.rb +12 -8
  36. data/lib/active_support/core_ext/string/xchar.rb +1 -1
  37. data/lib/active_support/core_ext/time/conversions.rb +1 -0
  38. data/lib/active_support/core_ext/time/marshal.rb +56 -0
  39. data/lib/active_support/dependencies.rb +146 -191
  40. data/lib/active_support/dependencies/autoload.rb +1 -0
  41. data/lib/active_support/deprecation/method_wrappers.rb +9 -9
  42. data/lib/active_support/deprecation/reporting.rb +2 -1
  43. data/lib/active_support/hash_with_indifferent_access.rb +4 -0
  44. data/lib/active_support/i18n.rb +2 -1
  45. data/lib/active_support/inflector/methods.rb +1 -1
  46. data/lib/active_support/inflector/transliterate.rb +3 -3
  47. data/lib/active_support/json/backends/yajl.rb +40 -0
  48. data/lib/active_support/json/decoding.rb +16 -1
  49. data/lib/active_support/lazy_load_hooks.rb +17 -0
  50. data/lib/active_support/memoizable.rb +1 -1
  51. data/lib/active_support/multibyte.rb +2 -2
  52. data/lib/active_support/multibyte/utils.rb +1 -1
  53. data/lib/active_support/notifications.rb +7 -3
  54. data/lib/active_support/notifications/fanout.rb +19 -5
  55. data/lib/active_support/ordered_options.rb +6 -0
  56. data/lib/active_support/railtie.rb +9 -9
  57. data/lib/active_support/ruby/shim.rb +2 -0
  58. data/lib/active_support/test_case.rb +2 -7
  59. data/lib/active_support/testing/assertions.rb +15 -0
  60. data/lib/active_support/testing/isolation.rb +2 -2
  61. data/lib/active_support/time.rb +1 -1
  62. data/lib/active_support/values/time_zone.rb +7 -4
  63. data/lib/active_support/version.rb +3 -2
  64. data/lib/active_support/whiny_nil.rb +4 -5
  65. data/lib/active_support/xml_mini/libxmlsax.rb +1 -0
  66. data/lib/active_support/xml_mini/nokogirisax.rb +1 -0
  67. data/lib/active_support/xml_mini/rexml.rb +7 -1
  68. metadata +65 -31
  69. data/lib/active_support/core_ext/kernel/daemonizing.rb +0 -7
  70. data/lib/active_support/core_ext/module/inclusion.rb +0 -30
  71. data/lib/active_support/core_ext/module/loading.rb +0 -25
  72. data/lib/active_support/core_ext/object/metaclass.rb +0 -13
  73. data/lib/active_support/core_ext/time/marshal_with_utc_flag.rb +0 -22
@@ -1,4 +1,5 @@
1
1
  require "active_support/inflector/methods"
2
+ require "active_support/lazy_load_hooks"
2
3
 
3
4
  module ActiveSupport
4
5
  module Autoload
@@ -12,15 +12,15 @@ module ActiveSupport
12
12
  method_names.each do |method_name|
13
13
  target_module.alias_method_chain(method_name, :deprecation) do |target, punctuation|
14
14
  target_module.module_eval(<<-end_eval, __FILE__, __LINE__ + 1)
15
- def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block)
16
- ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
17
- ::ActiveSupport::Deprecation.deprecated_method_warning( # ::ActiveSupport::Deprecation.deprecated_method_warning(
18
- :#{method_name}, # :generate_secret,
19
- #{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"),
20
- caller # caller
21
- ) # )
22
- send(:#{target}_without_deprecation#{punctuation}, *args, &block) # send(:generate_secret_without_deprecation, *args, &block)
23
- end # end
15
+ def #{target}_with_deprecation#{punctuation}(*args, &block)
16
+ ::ActiveSupport::Deprecation.warn(
17
+ ::ActiveSupport::Deprecation.deprecated_method_warning(
18
+ :#{method_name},
19
+ #{options[method_name].inspect}),
20
+ caller
21
+ )
22
+ send(:#{target}_without_deprecation#{punctuation}, *args, &block)
23
+ end
24
24
  end_eval
25
25
  end
26
26
  end
@@ -29,7 +29,8 @@ module ActiveSupport
29
29
  private
30
30
  def deprecation_message(callstack, message = nil)
31
31
  message ||= "You are using deprecated behavior which will be removed from the next major or minor release."
32
- "DEPRECATION WARNING: #{message}. #{deprecation_caller_message(callstack)}"
32
+ message += '.' unless message =~ /\.$/
33
+ "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}"
33
34
  end
34
35
 
35
36
  def deprecation_caller_message(callstack)
@@ -4,6 +4,10 @@
4
4
 
5
5
  module ActiveSupport
6
6
  class HashWithIndifferentAccess < Hash
7
+ def extractable_options?
8
+ true
9
+ end
10
+
7
11
  def initialize(constructor = {})
8
12
  if constructor.is_a?(Hash)
9
13
  super()
@@ -1,2 +1,3 @@
1
1
  require 'i18n'
2
- I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
2
+ I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
3
+ ActiveSupport.run_load_hooks(:i18n)
@@ -109,7 +109,7 @@ module ActiveSupport
109
109
 
110
110
  constant = Object
111
111
  names.each do |name|
112
- constant = constant.const_get(name, false) || constant.const_missing(name)
112
+ constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
113
113
  end
114
114
  constant
115
115
  end
@@ -14,8 +14,8 @@ module ActiveSupport
14
14
  if RUBY_VERSION >= '1.9'
15
15
  undef_method :transliterate
16
16
  def transliterate(string)
17
- warn "Ruby 1.9 doesn't support Unicode normalization yet"
18
- string.dup
17
+ proxy = ActiveSupport::Multibyte.proxy_class.new(string)
18
+ proxy.normalize(:kd).gsub(/[^\x00-\x7F]+/, '')
19
19
  end
20
20
 
21
21
  # The iconv transliteration code doesn't function correctly
@@ -47,7 +47,7 @@ module ActiveSupport
47
47
  # replace accented chars with their ascii equivalents
48
48
  parameterized_string = transliterate(string)
49
49
  # Turn unwanted chars into the separator
50
- parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
50
+ parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
51
51
  unless sep.nil? || sep.empty?
52
52
  re_sep = Regexp.escape(sep)
53
53
  # No more than one of the separator in a row.
@@ -0,0 +1,40 @@
1
+ require 'yajl-ruby' unless defined?(Yajl)
2
+
3
+ module ActiveSupport
4
+ module JSON
5
+ module Backends
6
+ module Yajl
7
+ ParseError = ::Yajl::ParseError
8
+ extend self
9
+
10
+ # Parses a JSON string or IO and convert it into an object
11
+ def decode(json)
12
+ data = ::Yajl::Parser.new.parse(json)
13
+ if ActiveSupport.parse_json_times
14
+ convert_dates_from(data)
15
+ else
16
+ data
17
+ end
18
+ end
19
+
20
+ private
21
+ def convert_dates_from(data)
22
+ case data
23
+ when nil
24
+ nil
25
+ when DATE_REGEX
26
+ DateTime.parse(data)
27
+ when Array
28
+ data.map! { |d| convert_dates_from(d) }
29
+ when Hash
30
+ data.each do |key, value|
31
+ data[key] = convert_dates_from(value)
32
+ end
33
+ else
34
+ data
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -6,12 +6,15 @@ module ActiveSupport
6
6
  mattr_accessor :parse_json_times
7
7
 
8
8
  module JSON
9
+ # Listed in order of preference.
10
+ DECODERS = %w(Yajl Yaml)
11
+
9
12
  class << self
10
13
  attr_reader :parse_error
11
14
  delegate :decode, :to => :backend
12
15
 
13
16
  def backend
14
- self.backend = "Yaml" unless defined?(@backend)
17
+ set_default_backend unless defined?(@backend)
15
18
  @backend
16
19
  end
17
20
 
@@ -31,6 +34,18 @@ module ActiveSupport
31
34
  ensure
32
35
  self.backend = old_backend
33
36
  end
37
+
38
+ def set_default_backend
39
+ DECODERS.find do |name|
40
+ begin
41
+ self.backend = name
42
+ true
43
+ rescue LoadError
44
+ # Try next decoder.
45
+ false
46
+ end
47
+ end
48
+ end
34
49
  end
35
50
  end
36
51
  end
@@ -0,0 +1,17 @@
1
+ module ActiveSupport
2
+ @load_hooks = Hash.new {|h,k| h[k] = [] }
3
+ @loaded = {}
4
+
5
+ def self.on_load(name, &block)
6
+ if base = @loaded[name]
7
+ base.instance_eval(&block)
8
+ else
9
+ @load_hooks[name] << block
10
+ end
11
+ end
12
+
13
+ def self.run_load_hooks(name, base = Object)
14
+ @load_hooks[name].each { |hook| base.instance_eval(&hook) }
15
+ @loaded[name] = base
16
+ end
17
+ end
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/object/metaclass'
1
+ require 'active_support/core_ext/object/singleton_class'
2
2
  require 'active_support/core_ext/module/aliasing'
3
3
 
4
4
  module ActiveSupport
@@ -53,8 +53,8 @@ module ActiveSupport #:nodoc:
53
53
  \xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf])\z /xn,
54
54
  # Quick check for valid Shift-JIS characters, disregards the odd-even pairing
55
55
  'Shift_JIS' => /\A(?:
56
- [\x00-\x7e \xa1-\xdf] |
57
- [\x81-\x9f \xe0-\xef] [\x40-\x7e \x80-\x9e \x9f-\xfc])\z /xn
56
+ [\x00-\x7e\xa1-\xdf] |
57
+ [\x81-\x9f\xe0-\xef] [\x40-\x7e\x80-\x9e\x9f-\xfc])\z /xn
58
58
  }
59
59
  end
60
60
  end
@@ -27,7 +27,7 @@ module ActiveSupport #:nodoc:
27
27
  def self.verify(string)
28
28
  if expression = valid_character
29
29
  # Splits the string on character boundaries, which are determined based on $KCODE.
30
- string.split(//).all? { |c| expression.match(c) }
30
+ string.split(//).all? { |c| expression =~ c }
31
31
  else
32
32
  true
33
33
  end
@@ -9,7 +9,7 @@ module ActiveSupport
9
9
  # end
10
10
  #
11
11
  # You can consume those events and the information they provide by registering
12
- # a subscriber. For instance, let's store all instrumented events in an array:
12
+ # a log subscriber. For instance, let's store all instrumented events in an array:
13
13
  #
14
14
  # @events = []
15
15
  #
@@ -35,7 +35,7 @@ module ActiveSupport
35
35
  # end
36
36
  #
37
37
  # Notifications ships with a queue implementation that consumes and publish events
38
- # to subscribers in a thread. You can use any queue implementation you want.
38
+ # to log subscribers in a thread. You can use any queue implementation you want.
39
39
  #
40
40
  module Notifications
41
41
  autoload :Instrumenter, 'active_support/notifications/instrumenter'
@@ -44,7 +44,7 @@ module ActiveSupport
44
44
 
45
45
  class << self
46
46
  attr_writer :notifier
47
- delegate :publish, :subscribe, :to => :notifier
47
+ delegate :publish, :subscribe, :unsubscribe, :to => :notifier
48
48
  delegate :instrument, :to => :instrumenter
49
49
 
50
50
  def notifier
@@ -69,6 +69,10 @@ module ActiveSupport
69
69
  @queue.bind(pattern).subscribe(&block)
70
70
  end
71
71
 
72
+ def unsubscribe(subscriber)
73
+ @queue.unsubscribe(subscriber)
74
+ end
75
+
72
76
  def wait
73
77
  @queue.wait
74
78
  end
@@ -1,10 +1,11 @@
1
1
  module ActiveSupport
2
2
  module Notifications
3
3
  # This is a default queue implementation that ships with Notifications. It
4
- # just pushes events to all registered subscribers.
4
+ # just pushes events to all registered log subscribers.
5
5
  class Fanout
6
6
  def initialize
7
7
  @subscribers = []
8
+ @listeners_for = {}
8
9
  end
9
10
 
10
11
  def bind(pattern)
@@ -12,11 +13,22 @@ module ActiveSupport
12
13
  end
13
14
 
14
15
  def subscribe(pattern = nil, &block)
16
+ @listeners_for.clear
15
17
  @subscribers << Subscriber.new(pattern, &block)
18
+ @subscribers.last
16
19
  end
17
20
 
18
- def publish(*args)
19
- @subscribers.each { |s| s.publish(*args) }
21
+ def unsubscribe(subscriber)
22
+ @subscribers.delete(subscriber)
23
+ @listeners_for.clear
24
+ end
25
+
26
+ def publish(name, *args)
27
+ if listeners = @listeners_for[name]
28
+ listeners.each { |s| s.publish(name, *args) }
29
+ else
30
+ @listeners_for[name] = @subscribers.select { |s| s.publish(name, *args) }
31
+ end
20
32
  end
21
33
 
22
34
  # This is a sync queue, so there is not waiting.
@@ -32,7 +44,7 @@ module ActiveSupport
32
44
  when Regexp, NilClass
33
45
  pattern
34
46
  else
35
- /^#{Regexp.escape(pattern.to_s)}/
47
+ /^#{Regexp.escape(pattern.to_s)}$/
36
48
  end
37
49
  end
38
50
 
@@ -48,7 +60,9 @@ module ActiveSupport
48
60
  end
49
61
 
50
62
  def publish(*args)
51
- push(*args) if matches?(args.first)
63
+ return unless matches?(args.first)
64
+ push(*args)
65
+ true
52
66
  end
53
67
 
54
68
  def drained?
@@ -18,4 +18,10 @@ module ActiveSupport #:nodoc:
18
18
  end
19
19
  end
20
20
  end
21
+
22
+ class InheritableOptions < OrderedOptions
23
+ def initialize(parent)
24
+ super() { |h,k| parent[k] }
25
+ end
26
+ end
21
27
  end
@@ -3,7 +3,7 @@ require "rails"
3
3
 
4
4
  module ActiveSupport
5
5
  class Railtie < Rails::Railtie
6
- railtie_name :active_support
6
+ config.active_support = ActiveSupport::OrderedOptions.new
7
7
 
8
8
  # Loads support for "whiny nil" (noisy warnings when methods are invoked
9
9
  # on +nil+ values) if Configuration#whiny_nils is true.
@@ -30,17 +30,17 @@ end
30
30
 
31
31
  module I18n
32
32
  class Railtie < Rails::Railtie
33
- railtie_name :i18n
34
-
35
- # Initialize I18n load paths to an array
36
- config.i18n.engines_load_path = []
33
+ config.i18n = ActiveSupport::OrderedOptions.new
34
+ config.i18n.railties_load_path = []
37
35
  config.i18n.load_path = []
38
36
 
39
37
  initializer "i18n.initialize" do
40
- require 'active_support/i18n'
41
-
42
- ActionDispatch::Callbacks.to_prepare do
38
+ ActiveSupport.on_load(:i18n) do
43
39
  I18n.reload!
40
+
41
+ ActionDispatch::Callbacks.to_prepare do
42
+ I18n.reload!
43
+ end
44
44
  end
45
45
  end
46
46
 
@@ -49,7 +49,7 @@ module I18n
49
49
  config.after_initialize do |app|
50
50
  app.config.i18n.each do |setting, value|
51
51
  case setting
52
- when :engines_load_path
52
+ when :railties_load_path
53
53
  app.config.i18n.load_path.unshift(*value)
54
54
  when :load_path
55
55
  I18n.load_path += value
@@ -17,3 +17,5 @@ require 'active_support/core_ext/string/conversions'
17
17
  require 'active_support/core_ext/string/interpolation'
18
18
  require 'active_support/core_ext/rexml'
19
19
  require 'active_support/core_ext/time/conversions'
20
+ require 'active_support/core_ext/file/path'
21
+ require 'active_support/core_ext/module/method_names'
@@ -5,9 +5,10 @@ require 'active_support/testing/deprecation'
5
5
  require 'active_support/testing/declarative'
6
6
  require 'active_support/testing/pending'
7
7
  require 'active_support/testing/isolation'
8
+ require 'active_support/core_ext/kernel/reporting'
8
9
 
9
10
  begin
10
- require 'mocha'
11
+ silence_warnings { require 'mocha' }
11
12
  rescue LoadError
12
13
  # Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
13
14
  Object.const_set :Mocha, Module.new
@@ -21,12 +22,6 @@ module ActiveSupport
21
22
  alias_method :method_name, :name if method_defined? :name
22
23
  alias_method :method_name, :__name__ if method_defined? :__name__
23
24
  else
24
- # TODO: Figure out how to get the Rails::BacktraceFilter into minitest/unit
25
- if defined?(Rails) && ENV['BACKTRACE'].nil?
26
- require 'rails/backtrace_cleaner'
27
- Test::Unit::Util::BacktraceFilter.module_eval { include Rails::BacktraceFilterForTestUnit }
28
- end
29
-
30
25
  Assertion = Test::Unit::AssertionFailedError
31
26
 
32
27
  require 'active_support/testing/default'
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/array/wrap'
2
+ require 'active_support/core_ext/object/blank'
2
3
 
3
4
  module ActiveSupport
4
5
  module Testing
@@ -62,6 +63,20 @@ module ActiveSupport
62
63
  def assert_no_difference(expression, message = nil, &block)
63
64
  assert_difference expression, 0, message, &block
64
65
  end
66
+
67
+ # Test if an expression is blank. Passes if object.blank? is true.
68
+ #
69
+ # assert_blank [] # => true
70
+ def assert_blank(object)
71
+ assert object.blank?, "#{object.inspect} is not blank"
72
+ end
73
+
74
+ # Test if an expression is not blank. Passes if object.present? is true.
75
+ #
76
+ # assert_present {:data => 'x' } # => true
77
+ def assert_present(object)
78
+ assert object.present?, "#{object.inspect} is blank"
79
+ end
65
80
  end
66
81
  end
67
82
  end
@@ -78,8 +78,8 @@ module ActiveSupport
78
78
  @@ran_class_setup = true
79
79
  end
80
80
 
81
- serialized = run_in_isolation do |runner|
82
- super(runner)
81
+ serialized = run_in_isolation do |isolated_runner|
82
+ super(isolated_runner)
83
83
  end
84
84
 
85
85
  retval, proxy = Marshal.load(serialized)
@@ -14,7 +14,7 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  require 'active_support/core_ext/time/publicize_conversion_methods'
17
- require 'active_support/core_ext/time/marshal_with_utc_flag'
17
+ require 'active_support/core_ext/time/marshal'
18
18
  require 'active_support/core_ext/time/acts_like'
19
19
  require 'active_support/core_ext/time/calculations'
20
20
  require 'active_support/core_ext/time/conversions'