aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Klishin <michael@novemberain.com>2008-12-28 13:21:10 +0300
committerMichael S. Klishin <michael@novemberain.com>2008-12-28 13:21:10 +0300
commitd77deb89d54b18c662ae3de103802e4d7a9d7d08 (patch)
treef5a77220f9057d3b998e1a2db8166ecc021e32cc
parent5da3ba12159d2c4fc0680efcf0cad8a31f725122 (diff)
downloadrails-d77deb89d54b18c662ae3de103802e4d7a9d7d08.tar.gz
rails-d77deb89d54b18c662ae3de103802e4d7a9d7d08.tar.bz2
rails-d77deb89d54b18c662ae3de103802e4d7a9d7d08.zip
Annotated metaprogramming code across ActiveSupport
-rw-r--r--actionpack/lib/action_controller/mime_responds.rb8
-rw-r--r--actionpack/test/controller/layout_test.rb22
-rw-r--r--activerecord/CHANGELOG2
-rwxr-xr-xactiverecord/lib/active_record/base.rb4
-rwxr-xr-xactiverecord/test/cases/base_test.rb5
-rw-r--r--activesupport/lib/active_support/buffered_logger.rb16
-rw-r--r--activesupport/lib/active_support/callbacks.rb28
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute_accessors.rb46
-rw-r--r--activesupport/lib/active_support/core_ext/class/delegating_attributes.rb42
-rw-r--r--activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb58
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb46
-rw-r--r--activesupport/lib/active_support/core_ext/proc.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/string/multibyte.rb6
-rw-r--r--activesupport/lib/active_support/deprecation.rb12
-rw-r--r--activesupport/lib/active_support/memoizable.rb52
-rw-r--r--activesupport/lib/active_support/minimalistic.rb15
-rw-r--r--activesupport/lib/active_support/multibyte/unicode_database.rb10
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb8
-rw-r--r--railties/lib/rails_generator/generators/applications/app/template_runner.rb119
-rw-r--r--railties/test/generators/rails_template_runner_test.rb190
20 files changed, 449 insertions, 246 deletions
diff --git a/actionpack/lib/action_controller/mime_responds.rb b/actionpack/lib/action_controller/mime_responds.rb
index c41bd3ac4b..b2b73bbd57 100644
--- a/actionpack/lib/action_controller/mime_responds.rb
+++ b/actionpack/lib/action_controller/mime_responds.rb
@@ -144,13 +144,9 @@ module ActionController #:nodoc:
def self.generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
const = sym.to_s.upcase
- class_eval <<-RUBY
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{sym}(&block) # def html(&block)
- if Mime::SET.include?(Mime::#{const}) # if Mime::Set.include?(Mime::HTML)
- custom(Mime::#{const}, &block) # custom(Mime::HTML, &block)
- else # else
- super # super
- end # end
+ custom(Mime::#{const}, &block) # custom(Mime::HTML, &block)
end # end
RUBY
end
diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb
index 18c01f755c..c2efe9d00b 100644
--- a/actionpack/test/controller/layout_test.rb
+++ b/actionpack/test/controller/layout_test.rb
@@ -165,15 +165,17 @@ class LayoutStatusIsRenderedTest < ActionController::TestCase
end
end
-class LayoutSymlinkedTest < LayoutTest
- layout "symlinked/symlinked_layout"
-end
-
-class LayoutSymlinkedIsRenderedTest < ActionController::TestCase
- def test_symlinked_layout_is_rendered
- @controller = LayoutSymlinkedTest.new
- get :hello
- assert_response 200
- assert_equal "layouts/symlinked/symlinked_layout", @response.layout
+unless RUBY_PLATFORM =~ /(:?mswin|mingw|bccwin)/
+ class LayoutSymlinkedTest < LayoutTest
+ layout "symlinked/symlinked_layout"
+ end
+
+ class LayoutSymlinkedIsRenderedTest < ActionController::TestCase
+ def test_symlinked_layout_is_rendered
+ @controller = LayoutSymlinkedTest.new
+ get :hello
+ assert_response 200
+ assert_equal "layouts/symlinked/symlinked_layout", @response.layout
+ end
end
end
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index d057ddfcd0..9cfd16cc0d 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*2.3.0/3.0*
+* Fixed that ActiveRecord::Base#new_record? should return false (not nil) for existing records #1219 [Yaroslav Markin]
+
* I18n the word separator for error messages. Introduces the activerecord.errors.format.separator translation key. #1294 [Akira Matsuda]
* Add :having as a key to find and the relevant associations. [Emilio Tagua]
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 9746a46d47..e5e94555eb 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -2406,9 +2406,9 @@ module ActiveRecord #:nodoc:
write_attribute(self.class.primary_key, value)
end
- # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet.
+ # Returns true if this object hasn't been saved yet -- that is, a record for the object doesn't exist yet; otherwise, returns false.
def new_record?
- defined?(@new_record) && @new_record
+ @new_record || false
end
# :call-seq:
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index ce77ba4dbf..0f03dae829 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1198,6 +1198,11 @@ class BasicsTest < ActiveRecord::TestCase
assert b_true.value?
end
+ def test_new_record_returns_boolean
+ assert_equal Topic.new.new_record?, true
+ assert_equal Topic.find(1).new_record?, false
+ end
+
def test_clone
topic = Topic.find(1)
cloned_topic = nil
diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb
index 445d8edf47..568c596f91 100644
--- a/activesupport/lib/active_support/buffered_logger.rb
+++ b/activesupport/lib/active_support/buffered_logger.rb
@@ -67,14 +67,14 @@ module ActiveSupport
end
for severity in Severity.constants
- class_eval <<-EOT, __FILE__, __LINE__
- def #{severity.downcase}(message = nil, progname = nil, &block)
- add(#{severity}, message, progname, &block)
- end
-
- def #{severity.downcase}?
- #{severity} >= @level
- end
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
+ def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
+ add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
+ end # end
+
+ def #{severity.downcase}? # def debug?
+ #{severity} >= @level # DEBUG >= @level
+ end # end
EOT
end
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 5cdcaf5ad1..aabf0a0895 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -209,21 +209,21 @@ module ActiveSupport
module ClassMethods
def define_callbacks(*callbacks)
callbacks.each do |callback|
- class_eval <<-"end_eval"
- def self.#{callback}(*methods, &block)
- callbacks = CallbackChain.build(:#{callback}, *methods, &block)
- (@#{callback}_callbacks ||= CallbackChain.new).concat callbacks
- end
+ class_eval <<-"end_eval", __FILE__, __LINE__ + 1
+ def self.#{callback}(*methods, &block) # def self.validate_on_create(*methods, &block)
+ callbacks = CallbackChain.build(:#{callback}, *methods, &block) # callbacks = CallbackChain.build(:validate_on_create, *methods, &block)
+ (@#{callback}_callbacks ||= CallbackChain.new).concat callbacks # (@validate_on_create_callbacks ||= CallbackChain.new).concat callbacks
+ end # end
- def self.#{callback}_callback_chain
- @#{callback}_callbacks ||= CallbackChain.new
-
- if superclass.respond_to?(:#{callback}_callback_chain)
- CallbackChain.new(superclass.#{callback}_callback_chain + @#{callback}_callbacks)
- else
- @#{callback}_callbacks
- end
- end
+ def self.#{callback}_callback_chain # def self.validate_on_create_callback_chain
+ @#{callback}_callbacks ||= CallbackChain.new # @validate_on_create_callbacks ||= CallbackChain.new
+ #
+ if superclass.respond_to?(:#{callback}_callback_chain) # if superclass.respond_to?(:validate_on_create_callback_chain)
+ CallbackChain.new(superclass.#{callback}_callback_chain + @#{callback}_callbacks) # CallbackChain.new(superclass.validate_on_create_callback_chain + @validate_on_create_callbacks)
+ else # else
+ @#{callback}_callbacks # @validate_on_create_callbacks
+ end # end
+ end # end
end_eval
end
end
diff --git a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
index 186ca69c05..6b2ac8b38b 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb
@@ -10,18 +10,18 @@ class Class
def cattr_reader(*syms)
syms.flatten.each do |sym|
next if sym.is_a?(Hash)
- class_eval(<<-EOS, __FILE__, __LINE__)
- unless defined? @@#{sym}
- @@#{sym} = nil
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ unless defined? @@#{sym} # unless defined @@property
+ @@#{sym} = nil # @@property = nil
+ end # end
- def self.#{sym}
- @@#{sym}
- end
+ def self.#{sym} # def self.property
+ @@#{sym} # @@property
+ end # end
- def #{sym}
- @@#{sym}
- end
+ def #{sym} # def property
+ @@#{sym} # @@property
+ end # end
EOS
end
end
@@ -29,19 +29,19 @@ class Class
def cattr_writer(*syms)
options = syms.extract_options!
syms.flatten.each do |sym|
- class_eval(<<-EOS, __FILE__, __LINE__)
- unless defined? @@#{sym}
- @@#{sym} = nil
- end
-
- def self.#{sym}=(obj)
- @@#{sym} = obj
- end
-
- #{"
- def #{sym}=(obj)
- @@#{sym} = obj
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ unless defined? @@#{sym} # unless defined? @@property
+ @@#{sym} = nil # @@property = nil
+ end # end
+
+ def self.#{sym}=(obj) # def self.property=(obj)
+ @@#{sym} = obj # @@property
+ end # end
+
+ #{"
+ def #{sym}=(obj) # def property=(obj)
+ @@#{sym} = obj # @@property = obj
+ end # end
" unless options[:instance_writer] == false }
EOS
end
diff --git a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
index 368317df9b..3b093a9a65 100644
--- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
@@ -8,33 +8,33 @@ class Class
def superclass_delegating_reader(*names)
class_name_to_stop_searching_on = self.superclass.name.blank? ? "Object" : self.superclass.name
names.each do |name|
- class_eval <<-EOS
- def self.#{name}
- if defined?(@#{name})
- @#{name}
- elsif superclass < #{class_name_to_stop_searching_on} && superclass.respond_to?(:#{name})
- superclass.#{name}
- end
- end
- def #{name}
- self.class.#{name}
- end
- def self.#{name}?
- !!#{name}
- end
- def #{name}?
- !!#{name}
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def self.#{name} # def self.property
+ if defined?(@#{name}) # if defined?(@property)
+ @#{name} # @property
+ elsif superclass < #{class_name_to_stop_searching_on} && superclass.respond_to?(:#{name}) # elseif superclass < Object && superclass.respond_to?(:property)
+ superclass.#{name} # superclass.property
+ end # end
+ end # end
+ def #{name} # def property
+ self.class.#{name} # self.class.property
+ end # end
+ def self.#{name}? # def self.property?
+ !!#{name} # !!property
+ end # end
+ def #{name}? # def property?
+ !!#{name} # !!property
+ end # end
EOS
end
end
def superclass_delegating_writer(*names)
names.each do |name|
- class_eval <<-EOS
- def self.#{name}=(value)
- @#{name} = value
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def self.#{name}=(value) # def self.property=(value)
+ @#{name} = value # @property = value
+ end # end
EOS
end
end
diff --git a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
index e6143a274b..8d0233ce9a 100644
--- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb
@@ -10,14 +10,14 @@ class Class # :nodoc:
def class_inheritable_reader(*syms)
syms.each do |sym|
next if sym.is_a?(Hash)
- class_eval <<-EOS
- def self.#{sym}
- read_inheritable_attribute(:#{sym})
- end
-
- def #{sym}
- self.class.#{sym}
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def self.#{sym} # def self.after_add
+ read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:after_add)
+ end # end
+
+ def #{sym} # def after_add
+ self.class.#{sym} # self.class.after_add
+ end # end
EOS
end
end
@@ -25,15 +25,15 @@ class Class # :nodoc:
def class_inheritable_writer(*syms)
options = syms.extract_options!
syms.each do |sym|
- class_eval <<-EOS
- def self.#{sym}=(obj)
- write_inheritable_attribute(:#{sym}, obj)
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def self.#{sym}=(obj) # def self.property=(obj)
+ write_inheritable_attribute(:#{sym}, obj) # write_inheritable_attribute(:property, obj)
+ end # end
#{"
- def #{sym}=(obj)
- self.class.#{sym} = obj
- end
+ def #{sym}=(obj) # def property=(obj)
+ self.class.#{sym} = obj # self.class.property = obj
+ end # end
" unless options[:instance_writer] == false }
EOS
end
@@ -42,15 +42,15 @@ class Class # :nodoc:
def class_inheritable_array_writer(*syms)
options = syms.extract_options!
syms.each do |sym|
- class_eval <<-EOS
- def self.#{sym}=(obj)
- write_inheritable_array(:#{sym}, obj)
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def self.#{sym}=(obj) # def self.property=(obj)
+ write_inheritable_array(:#{sym}, obj) # write_inheritable_array(:property, obj)
+ end # end
#{"
- def #{sym}=(obj)
- self.class.#{sym} = obj
- end
+ def #{sym}=(obj) # def property=(obj)
+ self.class.#{sym} = obj # self.class.property = obj
+ end # end
" unless options[:instance_writer] == false }
EOS
end
@@ -59,15 +59,15 @@ class Class # :nodoc:
def class_inheritable_hash_writer(*syms)
options = syms.extract_options!
syms.each do |sym|
- class_eval <<-EOS
- def self.#{sym}=(obj)
- write_inheritable_hash(:#{sym}, obj)
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def self.#{sym}=(obj) # def self.property=(obj)
+ write_inheritable_hash(:#{sym}, obj) # write_inheritable_hash(:property, obj)
+ end # end
#{"
- def #{sym}=(obj)
- self.class.#{sym} = obj
- end
+ def #{sym}=(obj) # def property=(obj)
+ self.class.#{sym} = obj # self.class.property = obj
+ end # end
" unless options[:instance_writer] == false }
EOS
end
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index 51e1c9af90..9467eb71ac 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -14,18 +14,18 @@ class Module
def mattr_reader(*syms)
syms.each do |sym|
next if sym.is_a?(Hash)
- class_eval(<<-EOS, __FILE__, __LINE__)
- unless defined? @@#{sym}
- @@#{sym} = nil
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ unless defined? @@#{sym} # unless defined? @@property
+ @@#{sym} = nil # @@ property = nil
+ end # end
- def self.#{sym}
- @@#{sym}
- end
+ def self.#{sym} # def self.property
+ @@#{sym} # @@property
+ end # end
- def #{sym}
- @@#{sym}
- end
+ def #{sym} # def property
+ @@#{sym} # @@property
+ end # end
EOS
end
end
@@ -33,19 +33,19 @@ class Module
def mattr_writer(*syms)
options = syms.extract_options!
syms.each do |sym|
- class_eval(<<-EOS, __FILE__, __LINE__)
- unless defined? @@#{sym}
- @@#{sym} = nil
- end
-
- def self.#{sym}=(obj)
- @@#{sym} = obj
- end
-
- #{"
- def #{sym}=(obj)
- @@#{sym} = obj
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ unless defined? @@#{sym} # unless defined? @@property
+ @@#{sym} = nil # @@ property = nil
+ end # end
+
+ def self.#{sym}=(obj) # def self.property=(obj)
+ @@#{sym} = obj # @@property = obj
+ end # end
+
+ #{"
+ def #{sym}=(obj) # def property=(obj)
+ @@#{sym} = obj # @@property = obj
+ end # end
" unless options[:instance_writer] == false }
EOS
end
diff --git a/activesupport/lib/active_support/core_ext/proc.rb b/activesupport/lib/active_support/core_ext/proc.rb
index 2ca23f62ef..5c29cc32a2 100644
--- a/activesupport/lib/active_support/core_ext/proc.rb
+++ b/activesupport/lib/active_support/core_ext/proc.rb
@@ -3,9 +3,9 @@ class Proc #:nodoc:
block, time = self, Time.now
(class << object; self end).class_eval do
method_name = "__bind_#{time.to_i}_#{time.usec}"
- define_method(method_name, &block)
- method = instance_method(method_name)
- remove_method(method_name)
+ define_method(method_name, &block) # define_method("__bind_1230458026_720454", &block)
+ method = instance_method(method_name) # method = instance_method("__bind_1230458026_720454")
+ remove_method(method_name) # remove_method("__bind_1230458026_720454")
method
end.bind(object)
end
diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb
index a4caa83b74..8f8f0968fd 100644
--- a/activesupport/lib/active_support/core_ext/string/multibyte.rb
+++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb
@@ -55,7 +55,11 @@ module ActiveSupport #:nodoc:
unless '1.8.7 and later'.respond_to?(:chars)
def chars
- ActiveSupport::Deprecation.warn('String#chars has been deprecated in favor of String#mb_chars.', caller)
+ # FIXME:
+ # ActiveSupport::Deprecation refers to RAILS_ENV
+ # and is a show stopper for 3rd party applications
+ # that only want ActiveSupport
+ ActiveSupport::Deprecation.warn('String#chars has been deprecated in favor of String#mb_chars.', caller) if defined?(ActiveSupport::Deprecation)
mb_chars
end
end
diff --git a/activesupport/lib/active_support/deprecation.rb b/activesupport/lib/active_support/deprecation.rb
index 25b26e9c96..d9bd40199f 100644
--- a/activesupport/lib/active_support/deprecation.rb
+++ b/activesupport/lib/active_support/deprecation.rb
@@ -89,11 +89,13 @@ module ActiveSupport
method_names = method_names + options.keys
method_names.each do |method_name|
alias_method_chain(method_name, :deprecation) do |target, punctuation|
- class_eval(<<-EOS, __FILE__, __LINE__)
- def #{target}_with_deprecation#{punctuation}(*args, &block)
- ::ActiveSupport::Deprecation.warn(self.class.deprecated_method_warning(:#{method_name}, #{options[method_name].inspect}), caller)
- #{target}_without_deprecation#{punctuation}(*args, &block)
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{target}_with_deprecation#{punctuation}(*args, &block) # def multi_with_reprecation(*args, &block)
+ ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
+ self.class.deprecated_method_warning(:#{method_name}, #{options[method_name].inspect}), # self.class.deprecated_method_warning(:multi, "this method is deprecated, blah, blah, blah")
+ caller) # caller)
+ #{target}_without_deprecation#{punctuation}(*args, &block) # multi_without_deprecation(*args, &block)
+ end # end
EOS
end
end
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index 9f2fd3a401..67ed10d58d 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -58,35 +58,35 @@ module ActiveSupport
original_method = :"_unmemoized_#{symbol}"
memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol)
- class_eval <<-EOS, __FILE__, __LINE__
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
include InstanceMethods
- raise "Already memoized #{symbol}" if method_defined?(:#{original_method})
- alias #{original_method} #{symbol}
+ raise "Already memoized #{symbol}" if method_defined?(:#{original_method}) # raise "Already memoized if_modified_since" if method_defined?(:__unmemoized_if_modified_since)
+ alias #{original_method} #{symbol} # alias __unmemoized_if_modified_since if_modified_since
- if instance_method(:#{symbol}).arity == 0
- def #{symbol}(reload = false)
- if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty?
- #{memoized_ivar} = [#{original_method}.freeze]
- end
- #{memoized_ivar}[0]
- end
- else
- def #{symbol}(*args)
- #{memoized_ivar} ||= {} unless frozen?
- reload = args.pop if args.last == true || args.last == :reload
-
- if defined?(#{memoized_ivar}) && #{memoized_ivar}
- if !reload && #{memoized_ivar}.has_key?(args)
- #{memoized_ivar}[args]
- elsif #{memoized_ivar}
- #{memoized_ivar}[args] = #{original_method}(*args).freeze
- end
- else
- #{original_method}(*args)
- end
- end
- end
+ if instance_method(:#{symbol}).arity == 0 # if instance_method(:if_modified_since).arity == 0
+ def #{symbol}(reload = false) # def if_modified_since(reload = false)
+ if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_if_modified_since) || @_memoized_if_modified_since.empty?
+ #{memoized_ivar} = [#{original_method}.freeze] # @_memoized_if_modified_since = [__unmemoized_if_modified_since.freeze]
+ end # end
+ #{memoized_ivar}[0] # @_memoized_if_modified_since[0]
+ end # end
+ else # else
+ def #{symbol}(*args) # def if_modified_since(*args)
+ #{memoized_ivar} ||= {} unless frozen? # @_memoized_if_modified_since ||= {} unless frozen?
+ reload = args.pop if args.last == true || args.last == :reload # reload = args.pop if args.last == true || args.last == :reload
+ #
+ if defined?(#{memoized_ivar}) && #{memoized_ivar} # if defined?(@_memoized_if_modified_since) && @_memoized_if_modified_since
+ if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_if_modified_since.has_key?(args)
+ #{memoized_ivar}[args] # @_memoized_if_modified_since[args]
+ elsif #{memoized_ivar} # elsif @_memoized_if_modified_since
+ #{memoized_ivar}[args] = #{original_method}(*args).freeze # @_memoized_if_modified_since[args] = __unmemoized_if_modified_since(*args).freeze
+ end # end
+ else # else
+ #{original_method}(*args) # __unmemoized_if_modified_since(*args)
+ end # end
+ end # end
+ end # end
EOS
end
end
diff --git a/activesupport/lib/active_support/minimalistic.rb b/activesupport/lib/active_support/minimalistic.rb
new file mode 100644
index 0000000000..ecb5de9eaa
--- /dev/null
+++ b/activesupport/lib/active_support/minimalistic.rb
@@ -0,0 +1,15 @@
+$LOAD_PATH.unshift File.dirname(__FILE__)
+
+require "core_ext/blank"
+# whole object.rb pulls up rare used introspection extensions
+require "core_ext/object/metaclass"
+require 'core_ext/array'
+require 'core_ext/hash'
+require 'core_ext/module/attribute_accessors'
+require 'multibyte'
+require 'core_ext/string/multibyte'
+require 'core_ext/string/inflections'
+
+class String
+ include ActiveSupport::CoreExtensions::String::Multibyte
+end
diff --git a/activesupport/lib/active_support/multibyte/unicode_database.rb b/activesupport/lib/active_support/multibyte/unicode_database.rb
index 3b8cf8f9eb..074ad8613a 100644
--- a/activesupport/lib/active_support/multibyte/unicode_database.rb
+++ b/activesupport/lib/active_support/multibyte/unicode_database.rb
@@ -23,11 +23,11 @@ module ActiveSupport #:nodoc:
# Lazy load the Unicode database so it's only loaded when it's actually used
ATTRIBUTES.each do |attr_name|
- class_eval(<<-EOS, __FILE__, __LINE__)
- def #{attr_name}
- load
- @#{attr_name}
- end
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
+ def #{attr_name} # def codepoints
+ load # load
+ @#{attr_name} # @codepoints
+ end # end
EOS
end
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 9a2d283b30..59f1e6163b 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -233,10 +233,10 @@ module ActiveSupport
end
%w(year mon month day mday wday yday hour min sec to_date).each do |method_name|
- class_eval <<-EOV
- def #{method_name}
- time.#{method_name}
- end
+ class_eval <<-EOV, __FILE__, __LINE__ + 1
+ def #{method_name} # def month
+ time.#{method_name} # time.month
+ end # end
EOV
end
diff --git a/railties/lib/rails_generator/generators/applications/app/template_runner.rb b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
index c6113648e6..4af85762aa 100644
--- a/railties/lib/rails_generator/generators/applications/app/template_runner.rb
+++ b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
@@ -8,23 +8,24 @@ require 'fileutils'
module Rails
class TemplateRunner
attr_reader :root
+ attr_writer :logger
def initialize(template, root = '') # :nodoc:
- @root = File.join(Dir.pwd, root)
+ @root = File.expand_path(File.directory?(root) ? root : File.join(Dir.pwd, root))
- puts "applying template: #{template}"
+ log 'applying', "template: #{template}"
load_template(template)
- puts "#{template} applied."
+ log 'applied', "#{template}"
end
def load_template(template)
begin
code = open(template).read
in_root { self.instance_eval(code) }
- rescue LoadError
- raise "The template [#{template}] could not be loaded."
+ rescue LoadError, Errno::ENOENT => e
+ raise "The template [#{template}] could not be loaded. Error: #{e}"
end
end
@@ -41,8 +42,8 @@ module Rails
#
# file("config/apach.conf", "your apache config")
#
- def file(filename, data = nil, &block)
- puts "creating file #{filename}"
+ def file(filename, data = nil, log_action = true, &block)
+ log 'file', filename if log_action
dir, file = [File.dirname(filename), File.basename(filename)]
inside(dir) do
@@ -66,7 +67,7 @@ module Rails
# plugin 'restful-authentication', :svn => 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
#
def plugin(name, options)
- puts "installing plugin #{name}"
+ log 'plugin', name
if options[:git] && options[:submodule]
in_root do
@@ -74,18 +75,17 @@ module Rails
end
elsif options[:git] || options[:svn]
in_root do
- `script/plugin install #{options[:svn] || options[:git]}`
+ run("script/plugin install #{options[:svn] || options[:git]}", false)
end
else
- puts "! no git or svn provided for #{name}. skipping..."
+ log "! no git or svn provided for #{name}. skipping..."
end
end
# Adds an entry into config/environment.rb for the supplied gem :
def gem(name, options = {})
- puts "adding gem #{name}"
+ log 'gem', name
- sentinel = 'Rails::Initializer.run do |config|'
gems_code = "config.gem '#{name}'"
if options.any?
@@ -93,9 +93,18 @@ module Rails
gems_code << ", #{opts}"
end
+ environment gems_code
+ end
+
+ # Adds a line inside the Initializer block for config/environment.rb. Used by #gem
+ def environment(data = nil, &block)
+ sentinel = 'Rails::Initializer.run do |config|'
+
+ data = block.call if !data && block_given?
+
in_root do
gsub_file 'config/environment.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
- "#{match}\n #{gems_code}"
+ "#{match}\n " << data
end
end
end
@@ -111,11 +120,11 @@ module Rails
def git(command = {})
in_root do
if command.is_a?(Symbol)
- puts "running git #{command}"
+ log 'running', "git #{command}"
Git.run(command.to_s)
else
command.each do |command, options|
- puts "running git #{command} #{options}"
+ log 'running', "git #{command} #{options}"
Git.run("#{command} #{options}")
end
end
@@ -135,16 +144,8 @@ module Rails
# vendor("foreign.rb", "# Foreign code is fun")
#
def vendor(filename, data = nil, &block)
- puts "vendoring file #{filename}"
- inside("vendor") do |folder|
- File.open("#{folder}/#{filename}", "w") do |f|
- if block_given?
- f.write(block.call)
- else
- f.write(data)
- end
- end
- end
+ log 'vendoring', filename
+ file("vendor/#{filename}", data, false, &block)
end
# Create a new file in the lib/ directory. Code can be specified
@@ -158,17 +159,9 @@ module Rails
#
# lib("foreign.rb", "# Foreign code is fun")
#
- def lib(filename, data = nil)
- puts "add lib file #{filename}"
- inside("lib") do |folder|
- File.open("#{folder}/#{filename}", "w") do |f|
- if block_given?
- f.write(block.call)
- else
- f.write(data)
- end
- end
- end
+ def lib(filename, data = nil, &block)
+ log 'lib', filename
+ file("lib/#{filename}", data, false, &block)
end
# Create a new Rakefile with the provided code (either in a block or a string).
@@ -190,16 +183,8 @@ module Rails
# rakefile("seed.rake", "puts 'im plantin ur seedz'")
#
def rakefile(filename, data = nil, &block)
- puts "adding rakefile #{filename}"
- inside("lib/tasks") do |folder|
- File.open("#{folder}/#{filename}", "w") do |f|
- if block_given?
- f.write(block.call)
- else
- f.write(data)
- end
- end
- end
+ log 'rakefile', filename
+ file("lib/tasks/#{filename}", data, false, &block)
end
# Create a new initializer with the provided code (either in a block or a string).
@@ -219,16 +204,8 @@ module Rails
# initializer("api.rb", "API_KEY = '123456'")
#
def initializer(filename, data = nil, &block)
- puts "adding initializer #{filename}"
- inside("config/initializers") do |folder|
- File.open("#{folder}/#{filename}", "w") do |f|
- if block_given?
- f.write(block.call)
- else
- f.write(data)
- end
- end
- end
+ log 'initializer', filename
+ file("config/initializers/#{filename}", data, false, &block)
end
# Generate something using a generator from Rails or a plugin.
@@ -240,10 +217,10 @@ module Rails
# generate(:authenticated, "user session")
#
def generate(what, *args)
- puts "generating #{what}"
+ log 'generating', what
argument = args.map(&:to_s).flatten.join(" ")
- in_root { `#{root}/script/generate #{what} #{argument}` }
+ in_root { run("script/generate #{what} #{argument}", false) }
end
# Executes a command
@@ -254,8 +231,8 @@ module Rails
# run('ln -s ~/edge rails)
# end
#
- def run(command)
- puts "executing #{command} from #{Dir.pwd}"
+ def run(command, log_action = true)
+ log 'executing', "#{command} from #{Dir.pwd}" if log_action
`#{command}`
end
@@ -268,10 +245,10 @@ module Rails
# rake("gems:install", :sudo => true)
#
def rake(command, options = {})
- puts "running rake task #{command}"
+ log 'rake', command
env = options[:env] || 'development'
sudo = options[:sudo] ? 'sudo ' : ''
- in_root { `#{sudo}rake #{command} RAILS_ENV=#{env}` }
+ in_root { run("#{sudo}rake #{command} RAILS_ENV=#{env}", false) }
end
# Just run the capify command in root
@@ -281,7 +258,8 @@ module Rails
# capify!
#
def capify!
- in_root { `capify .` }
+ log 'capifying'
+ in_root { run('capify .', false) }
end
# Add Rails to /vendor/rails
@@ -291,8 +269,8 @@ module Rails
# freeze!
#
def freeze!(args = {})
- puts "vendoring rails edge"
- in_root { `rake rails:freeze:edge` }
+ log 'vendor', 'rails edge'
+ in_root { run('rake rails:freeze:edge', false) }
end
# Make an entry in Rails routing file conifg/routes.rb
@@ -302,6 +280,7 @@ module Rails
# route "map.root :controller => :welcome"
#
def route(routing_code)
+ log 'route', routing_code
sentinel = 'ActionController::Routing::Routes.draw do |map|'
in_root do
@@ -321,7 +300,7 @@ module Rails
# freeze! if ask("Should I freeze the latest Rails?") == "yes"
#
def ask(string)
- puts string
+ log '', string
gets.strip
end
@@ -368,5 +347,13 @@ module Rails
def destination_path(relative_destination)
File.join(root, relative_destination)
end
+
+ def log(action, message = '')
+ logger.log(action, message)
+ end
+
+ def logger
+ @logger ||= Rails::Generator::Base.logger
+ end
end
end \ No newline at end of file
diff --git a/railties/test/generators/rails_template_runner_test.rb b/railties/test/generators/rails_template_runner_test.rb
new file mode 100644
index 0000000000..07507a16c4
--- /dev/null
+++ b/railties/test/generators/rails_template_runner_test.rb
@@ -0,0 +1,190 @@
+require 'abstract_unit'
+require 'generators/generator_test_helper'
+
+class RailsTemplateRunnerTest < GeneratorTestCase
+ def setup
+ Rails::Generator::Base.use_application_sources!
+ run_generator('app', [RAILS_ROOT])
+ # generate empty template
+ @template_path = File.join(RAILS_ROOT, 'template.rb')
+ File.open(File.join(@template_path), 'w') {|f| f << '' }
+
+ @git_plugin_uri = 'git://github.com/technoweenie/restful-authentication.git'
+ @svn_plugin_uri = 'svn://svnhub.com/technoweenie/restful-authentication/trunk'
+ end
+
+ def teardown
+ super
+ rm_rf "#{RAILS_ROOT}/README"
+ rm_rf "#{RAILS_ROOT}/Rakefile"
+ rm_rf "#{RAILS_ROOT}/doc"
+ rm_rf "#{RAILS_ROOT}/lib"
+ rm_rf "#{RAILS_ROOT}/log"
+ rm_rf "#{RAILS_ROOT}/script"
+ rm_rf "#{RAILS_ROOT}/vendor"
+ rm_rf "#{RAILS_ROOT}/tmp"
+ rm_rf "#{RAILS_ROOT}/Capfile"
+ rm_rf @template_path
+ end
+
+ def test_initialize_should_load_template
+ Rails::TemplateRunner.any_instance.expects(:load_template).with(@template_path)
+ silence_generator do
+ Rails::TemplateRunner.new(@template_path, RAILS_ROOT)
+ end
+ end
+
+ def test_initialize_should_raise_error_on_missing_template_file
+ assert_raise(RuntimeError) do
+ silence_generator do
+ Rails::TemplateRunner.new('non/existent/path/to/template.rb', RAILS_ROOT)
+ end
+ end
+ end
+
+ def test_file_should_write_data_to_file_path
+ run_template_method(:file, 'lib/test_file.rb', 'heres test data')
+ assert_generated_file_with_data 'lib/test_file.rb', 'heres test data'
+ end
+
+ def test_file_should_write_block_contents_to_file_path
+ run_template_method(:file, 'lib/test_file.rb') { 'heres block data' }
+ assert_generated_file_with_data 'lib/test_file.rb', 'heres block data'
+ end
+
+ def test_plugin_with_git_option_should_run_plugin_install
+ expects_run_with_command("script/plugin install #{@git_plugin_uri}")
+ run_template_method(:plugin, 'restful-authentication', :git => @git_plugin_uri)
+ end
+
+ def test_plugin_with_svn_option_should_run_plugin_install
+ expects_run_with_command("script/plugin install #{@svn_plugin_uri}")
+ run_template_method(:plugin, 'restful-authentication', :svn => @svn_plugin_uri)
+ end
+
+ def test_plugin_with_git_option_and_submodule_should_use_git_scm
+ Rails::Git.expects(:run).with("submodule add #{@git_plugin_uri} vendor/plugins/rest_auth")
+ run_template_method(:plugin, 'rest_auth', :git => @git_plugin_uri, :submodule => true)
+ end
+
+ def test_plugin_with_no_options_should_skip_method
+ Rails::TemplateRunner.any_instance.expects(:run).never
+ run_template_method(:plugin, 'rest_auth', {})
+ end
+
+ def test_gem_should_put_gem_dependency_in_enviroment
+ run_template_method(:gem, 'will-paginate')
+ assert_rails_initializer_includes("config.gem 'will-paginate'")
+ end
+
+ def test_gem_with_options_should_include_options_in_gem_dependency_in_environment
+ run_template_method(:gem, 'mislav-will-paginate', :lib => 'will-paginate', :source => 'http://gems.github.com')
+ assert_rails_initializer_includes("config.gem 'mislav-will-paginate', :source => 'http://gems.github.com', :lib => 'will-paginate'")
+ end
+
+ def test_environment_should_include_data_in_environment_initializer_block
+ load_paths = 'config.load_paths += %w["#{RAILS_ROOT}/app/extras"]'
+ run_template_method(:environment, load_paths)
+ assert_rails_initializer_includes(load_paths)
+ end
+
+ def test_environment_with_block_should_include_block_contents_in_environment_initializer_block
+ run_template_method(:environment) do
+ '# This wont be added'
+ '# This will be added'
+ end
+ assert_rails_initializer_includes('# This will be added')
+ end
+
+ def test_git_with_symbol_should_run_command_using_git_scm
+ Rails::Git.expects(:run).once.with('init')
+ run_template_method(:git, :init)
+ end
+
+ def test_git_with_hash_should_run_each_command_using_git_scm
+ Rails::Git.expects(:run).times(2)
+ run_template_method(:git, {:init => '', :add => '.'})
+ end
+
+ def test_vendor_should_write_data_to_file_in_vendor
+ run_template_method(:vendor, 'vendor_file.rb', '# vendor data')
+ assert_generated_file_with_data('vendor/vendor_file.rb', '# vendor data')
+ end
+
+ def test_lib_should_write_data_to_file_in_lib
+ run_template_method(:lib, 'my_library.rb', 'class MyLibrary')
+ assert_generated_file_with_data('lib/my_library.rb', 'class MyLibrary')
+ end
+
+ def test_rakefile_should_write_date_to_file_in_lib_tasks
+ run_template_method(:rakefile, 'myapp.rake', 'task :run => [:environment]')
+ assert_generated_file_with_data('lib/tasks/myapp.rake', 'task :run => [:environment]')
+ end
+
+ def test_initializer_should_write_date_to_file_in_config_initializers
+ run_template_method(:initializer, 'constants.rb', 'MY_CONSTANT = 42')
+ assert_generated_file_with_data('config/initializers/constants.rb', 'MY_CONSTANT = 42')
+ end
+
+ def test_generate_should_run_script_generate_with_argument_and_options
+ expects_run_with_command('script/generate model MyModel')
+ run_template_method(:generate, 'model', 'MyModel')
+ end
+
+ def test_rake_should_run_rake_command_with_development_env
+ expects_run_with_command('rake log:clear RAILS_ENV=development')
+ run_template_method(:rake, 'log:clear')
+ end
+
+ def test_rake_with_env_option_should_run_rake_command_in_env
+ expects_run_with_command('rake log:clear RAILS_ENV=production')
+ run_template_method(:rake, 'log:clear', :env => 'production')
+ end
+
+ def test_rake_with_sudo_option_should_run_rake_command_with_sudo
+ expects_run_with_command('sudo rake log:clear RAILS_ENV=development')
+ run_template_method(:rake, 'log:clear', :sudo => true)
+ end
+
+ def test_capify_should_run_the_capify_command
+ expects_run_with_command('capify .')
+ run_template_method(:capify!)
+ end
+
+ def test_freeze_should_freeze_rails_edge
+ expects_run_with_command('rake rails:freeze:edge')
+ run_template_method(:freeze!)
+ end
+
+ def test_route_should_add_data_to_the_routes_block_in_config_routes
+ route_command = "map.route '/login', :controller => 'sessions', :action => 'new'"
+ run_template_method(:route, route_command)
+ assert_generated_file_with_data 'config/routes.rb', route_command
+ end
+
+ protected
+ def run_template_method(method_name, *args, &block)
+ silence_generator do
+ @template_runner = Rails::TemplateRunner.new(@template_path, RAILS_ROOT)
+ @template_runner.send(method_name, *args, &block)
+ end
+ end
+
+ def expects_run_with_command(command)
+ Rails::TemplateRunner.any_instance.stubs(:run).once.with(command, false)
+ end
+
+ def assert_rails_initializer_includes(data, message = nil)
+ message ||= "Rails::Initializer should include #{data}"
+ assert_generated_file 'config/environment.rb' do |body|
+ assert_match(/#{Regexp.escape("Rails::Initializer.run do |config|")}.+#{Regexp.escape(data)}.+end/m, body, message)
+ end
+ end
+
+ def assert_generated_file_with_data(file, data, message = nil)
+ message ||= "#{file} should include '#{data}'"
+ assert_generated_file(file) do |file|
+ assert_match(/#{Regexp.escape(data)}/,file, message)
+ end
+ end
+end \ No newline at end of file