diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2008-12-28 20:00:29 +0000 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2008-12-28 20:00:29 +0000 |
commit | d6c2285e31cbc7150cf99ff3a537eddbdb50fb29 (patch) | |
tree | 785f0c7ad566a09b9bc558854b4a5d43ae86ed46 | |
parent | aaea12c497ca86a86fbda8409c226630ade22f89 (diff) | |
parent | a2270ef2594b97891994848138614657363f2806 (diff) | |
download | rails-d6c2285e31cbc7150cf99ff3a537eddbdb50fb29.tar.gz rails-d6c2285e31cbc7150cf99ff3a537eddbdb50fb29.tar.bz2 rails-d6c2285e31cbc7150cf99ff3a537eddbdb50fb29.zip |
Merge commit 'mainstream/master'
47 files changed, 769 insertions, 411 deletions
diff --git a/actionpack/lib/action_controller/assertions/selector_assertions.rb b/actionpack/lib/action_controller/assertions/selector_assertions.rb index 248ca85994..7f8fe9ab19 100644 --- a/actionpack/lib/action_controller/assertions/selector_assertions.rb +++ b/actionpack/lib/action_controller/assertions/selector_assertions.rb @@ -402,6 +402,7 @@ module ActionController if rjs_type if rjs_type == :insert position = args.shift + id = args.shift insertion = "insert_#{position}".to_sym raise ArgumentError, "Unknown RJS insertion type #{position}" unless RJS_STATEMENTS[insertion] statement = "(#{RJS_STATEMENTS[insertion]})" diff --git a/actionpack/lib/action_controller/helpers.rb b/actionpack/lib/action_controller/helpers.rb index 402750c57d..ba65032f6a 100644 --- a/actionpack/lib/action_controller/helpers.rb +++ b/actionpack/lib/action_controller/helpers.rb @@ -163,9 +163,9 @@ module ActionController #:nodoc: def helper_method(*methods) methods.flatten.each do |method| master_helper_module.module_eval <<-end_eval - def #{method}(*args, &block) - controller.send(%(#{method}), *args, &block) - end + def #{method}(*args, &block) # def current_user(*args, &block) + controller.send(%(#{method}), *args, &block) # controller.send(%(current_user), *args, &block) + end # end end_eval end end diff --git a/actionpack/lib/action_controller/mime_responds.rb b/actionpack/lib/action_controller/mime_responds.rb index 29294476f7..b755363873 100644 --- a/actionpack/lib/action_controller/mime_responds.rb +++ b/actionpack/lib/action_controller/mime_responds.rb @@ -143,12 +143,27 @@ module ActionController #:nodoc: custom(@mime_type_priority.first, &block) end end + + def self.generate_method_for_mime(mime) + sym = mime.is_a?(Symbol) ? mime : mime.to_sym + const = sym.to_s.upcase + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{sym}(&block) # def html(&block) + custom(Mime::#{const}, &block) # custom(Mime::HTML, &block) + end # end + RUBY + end - def method_missing(symbol, &block) - mime_constant = symbol.to_s.upcase + Mime::SET.each do |mime| + generate_method_for_mime(mime) + end - if Mime::SET.include?(Mime.const_get(mime_constant)) - custom(Mime.const_get(mime_constant), &block) + def method_missing(symbol, &block) + mime_constant = Mime.const_get(symbol.to_s.upcase) + + if Mime::SET.include?(mime_constant) + self.class.generate_method_for_mime(mime_constant) + send(symbol, &block) else super end diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index dce50c6c3b..924d1aa6bd 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -118,13 +118,17 @@ module ActionController %w(edit new).each do |action| module_eval <<-EOT, __FILE__, __LINE__ - def #{action}_polymorphic_url(record_or_hash, options = {}) - polymorphic_url(record_or_hash, options.merge(:action => "#{action}")) - end - - def #{action}_polymorphic_path(record_or_hash, options = {}) - polymorphic_url(record_or_hash, options.merge(:action => "#{action}", :routing_type => :path)) - end + def #{action}_polymorphic_url(record_or_hash, options = {}) # def edit_polymorphic_url(record_or_hash, options = {}) + polymorphic_url( # polymorphic_url( + record_or_hash, # record_or_hash, + options.merge(:action => "#{action}")) # options.merge(:action => "edit")) + end # end + # + def #{action}_polymorphic_path(record_or_hash, options = {}) # def edit_polymorphic_path(record_or_hash, options = {}) + polymorphic_url( # polymorphic_url( + record_or_hash, # record_or_hash, + options.merge(:action => "#{action}", :routing_type => :path)) # options.merge(:action => "edit", :routing_type => :path)) + end # end EOT end diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 732172668e..ab028b9eb2 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -288,7 +288,7 @@ EOM if forwarded = env["HTTP_X_FORWARDED_HOST"] forwarded.split(/,\s?/).last else - env['HTTP_HOST'] || env['SERVER_NAME'] || "#{env['SERVER_ADDR']}:#{env['SERVER_PORT']}" + env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}" end end diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb index 13646aef61..5975977365 100644 --- a/actionpack/lib/action_controller/routing/route_set.rb +++ b/actionpack/lib/action_controller/routing/route_set.rb @@ -145,10 +145,10 @@ module ActionController def define_hash_access(route, name, kind, options) selector = hash_access_name(name, kind) named_helper_module_eval <<-end_eval # We use module_eval to avoid leaks - def #{selector}(options = nil) - options ? #{options.inspect}.merge(options) : #{options.inspect} - end - protected :#{selector} + def #{selector}(options = nil) # def hash_for_users_url(options = nil) + options ? #{options.inspect}.merge(options) : #{options.inspect} # options ? {:only_path=>false}.merge(options) : {:only_path=>false} + end # end + protected :#{selector} # protected :hash_for_users_url end_eval helpers << selector end @@ -173,32 +173,33 @@ module ActionController # foo_url(bar, baz, bang, :sort_by => 'baz') # named_helper_module_eval <<-end_eval # We use module_eval to avoid leaks - def #{selector}(*args) - - #{generate_optimisation_block(route, kind)} - - opts = if args.empty? || Hash === args.first - args.first || {} - else - options = args.extract_options! - args = args.zip(#{route.segment_keys.inspect}).inject({}) do |h, (v, k)| - h[k] = v - h - end - options.merge(args) - end - - url_for(#{hash_access_method}(opts)) - - end - #Add an alias to support the now deprecated formatted_* URL. - def formatted_#{selector}(*args) - ActiveSupport::Deprecation.warn( - "formatted_#{selector}() has been deprecated. please pass format to the standard" + - "#{selector}() method instead.", caller) - #{selector}(*args) - end - protected :#{selector} + def #{selector}(*args) # def users_url(*args) + # + #{generate_optimisation_block(route, kind)} # #{generate_optimisation_block(route, kind)} + # + opts = if args.empty? || Hash === args.first # opts = if args.empty? || Hash === args.first + args.first || {} # args.first || {} + else # else + options = args.extract_options! # options = args.extract_options! + args = args.zip(#{route.segment_keys.inspect}).inject({}) do |h, (v, k)| # args = args.zip([]).inject({}) do |h, (v, k)| + h[k] = v # h[k] = v + h # h + end # end + options.merge(args) # options.merge(args) + end # end + # + url_for(#{hash_access_method}(opts)) # url_for(hash_for_users_url(opts)) + # + end # end + #Add an alias to support the now deprecated formatted_* URL. # #Add an alias to support the now deprecated formatted_* URL. + def formatted_#{selector}(*args) # def formatted_users_url(*args) + ActiveSupport::Deprecation.warn( # ActiveSupport::Deprecation.warn( + "formatted_#{selector}() has been deprecated. " + # "formatted_users_url() has been deprecated. " + + "please pass format to the standard" + # "please pass format to the standard" + + "#{selector}() method instead.", caller) # "users_url() method instead.", caller) + #{selector}(*args) # users_url(*args) + end # end + protected :#{selector} # protected :users_url end_eval helpers << selector end diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index acfb10cdca..285a8b09e4 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -33,11 +33,7 @@ module ActionController #:nodoc: attr_accessor :host def initialize - env = Rack::MockRequest.env_for("/") - - # TODO: Fix Request to assume env['SERVER_ADDR'] doesn't contain port number - env['SERVER_ADDR'] = env.delete("SERVER_NAME") - super(env) + super(Rack::MockRequest.env_for("/")) @query_parameters = {} @session = TestSession.new diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 621e2946b5..a85751c657 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -737,9 +737,13 @@ module ActionView (field_helpers - %w(label check_box radio_button fields_for)).each do |selector| src = <<-end_src - def #{selector}(method, options = {}) - @template.send(#{selector.inspect}, @object_name, method, objectify_options(options)) - end + def #{selector}(method, options = {}) # def text_field(method, options = {}) + @template.send( # @template.send( + #{selector.inspect}, # "text_field", + @object_name, # @object_name, + method, # method, + objectify_options(options)) # objectify_options(options)) + end # end end_src class_eval src, __FILE__, __LINE__ end diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index ed8c4427c9..99c57c0c91 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -248,6 +248,14 @@ class AssertSelectTest < ActionController::TestCase end end + def test_assert_select_rjs_for_positioned_insert_should_fail_when_mixing_arguments + render_rjs do |page| + page.insert_html :top, "test1", "<div id=\"1\">foo</div>" + page.insert_html :bottom, "test2", "<div id=\"2\">foo</div>" + end + assert_raises(Assertion) {assert_select_rjs :insert, :top, "test2"} + end + # # Test css_select. # 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/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 406e2b2818..31bff4ae6d 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -4,7 +4,7 @@ class BaseRackTest < Test::Unit::TestCase def setup @env = { "HTTP_MAX_FORWARDS" => "10", - "SERVER_NAME" => "glu.ttono.us:8007", + "SERVER_NAME" => "glu.ttono.us", "FCGI_ROLE" => "RESPONDER", "AUTH_TYPE" => "Basic", "HTTP_X_FORWARDED_HOST" => "glu.ttono.us", @@ -145,7 +145,7 @@ class RackRequestTest < BaseRackTest assert_equal "kevin", @request.remote_user assert_equal :get, @request.request_method assert_equal "/dispatch.fcgi", @request.script_name - assert_equal "glu.ttono.us:8007", @request.server_name + assert_equal "glu.ttono.us", @request.server_name assert_equal 8007, @request.server_port assert_equal "HTTP/1.1", @request.server_protocol assert_equal "lighttpd", @request.server_software diff --git a/actionpack/test/controller/session/cookie_store_test.rb b/actionpack/test/controller/session/cookie_store_test.rb index 69aec59dc0..d349c18d1d 100644 --- a/actionpack/test/controller/session/cookie_store_test.rb +++ b/actionpack/test/controller/session/cookie_store_test.rb @@ -25,7 +25,7 @@ class CookieStoreTest < ActionController::IntegrationTest def set_session_value session[:foo] = "bar" - render :text => Marshal.dump(session.to_hash) + render :text => Verifier.generate(session.to_hash) end def get_session_value @@ -94,8 +94,7 @@ class CookieStoreTest < ActionController::IntegrationTest with_test_route_set do get '/set_session_value' assert_response :success - session_payload = Verifier.generate(Marshal.load(response.body)) - assert_equal ["_myapp_session=#{session_payload}; path=/"], + assert_equal ["_myapp_session=#{response.body}; path=/"], headers['Set-Cookie'] end end @@ -148,8 +147,8 @@ class CookieStoreTest < ActionController::IntegrationTest with_test_route_set do get '/set_session_value' assert_response :success - session_payload = Verifier.generate(Marshal.load(response.body)) - assert_equal ["_myapp_session=#{session_payload}; path=/"], + session_payload = response.body + assert_equal ["_myapp_session=#{response.body}; path=/"], headers['Set-Cookie'] get '/call_reset_session' 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/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 7b1b2d9ad9..9d0bf3a308 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -43,7 +43,7 @@ module ActiveRecord # loading in a more high-level (application developer-friendly) manner. module ClassMethods protected - + # Eager loads the named associations for the given ActiveRecord record(s). # # In this description, 'association name' shall refer to the name passed @@ -94,8 +94,8 @@ module ActiveRecord raise "parent must be an association name" unless parent.is_a?(String) || parent.is_a?(Symbol) preload_associations(records, parent, preload_options) reflection = reflections[parent] - parents = records.map {|record| record.send(reflection.name)}.flatten - unless parents.empty? || parents.first.nil? + parents = records.map {|record| record.send(reflection.name)}.flatten.compact + unless parents.empty? parents.first.class.preload_associations(parents, child) end end @@ -113,7 +113,7 @@ module ActiveRecord # unnecessarily records.group_by {|record| class_to_reflection[record.class] ||= record.class.reflections[association]}.each do |reflection, records| raise ConfigurationError, "Association named '#{ association }' was not found; perhaps you misspelled it?" unless reflection - + # 'reflection.macro' can return 'belongs_to', 'has_many', etc. Thus, # the following could call 'preload_belongs_to_association', # 'preload_has_many_association', etc. @@ -128,7 +128,7 @@ module ActiveRecord association_proxy.target.push(*[associated_record].flatten) end end - + def add_preloaded_record_to_collection(parent_records, reflection_name, associated_record) parent_records.each do |parent_record| parent_record.send("set_#{reflection_name}_target", associated_record) @@ -183,18 +183,19 @@ module ActiveRecord conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}" conditions << append_conditions(reflection, preload_options) - associated_records = reflection.klass.find(:all, :conditions => [conditions, ids], - :include => options[:include], - :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}", - :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id", - :order => options[:order]) - + associated_records = reflection.klass.with_exclusive_scope do + reflection.klass.find(:all, :conditions => [conditions, ids], + :include => options[:include], + :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}", + :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id", + :order => options[:order]) + end set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id') end def preload_has_one_association(records, reflection, preload_options={}) return if records.first.send("loaded_#{reflection.name}?") - id_to_record_map, ids = construct_id_map(records) + id_to_record_map, ids = construct_id_map(records) options = reflection.options records.each {|record| record.send("set_#{reflection.name}_target", nil)} if options[:through] @@ -248,7 +249,7 @@ module ActiveRecord reflection.primary_key_name) end end - + def preload_through_records(records, reflection, through_association) through_reflection = reflections[through_association] through_primary_key = through_reflection.primary_key_name @@ -333,11 +334,13 @@ module ActiveRecord end conditions = "#{table_name}.#{connection.quote_column_name(primary_key)} #{in_or_equals_for_ids(ids)}" conditions << append_conditions(reflection, preload_options) - associated_records = klass.find(:all, :conditions => [conditions, ids], + associated_records = klass.with_exclusive_scope do + klass.find(:all, :conditions => [conditions, ids], :include => options[:include], :select => options[:select], :joins => options[:joins], :order => options[:order]) + end set_association_single_records(id_map, reflection.name, associated_records, primary_key) end end @@ -355,13 +358,15 @@ module ActiveRecord conditions << append_conditions(reflection, preload_options) - reflection.klass.find(:all, + reflection.klass.with_exclusive_scope do + reflection.klass.find(:all, :select => (preload_options[:select] || options[:select] || "#{table_name}.*"), :include => preload_options[:include] || options[:include], :conditions => [conditions, ids], :joins => options[:joins], :group => preload_options[:group] || options[:group], :order => preload_options[:order] || options[:order]) + end end diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 5a60b13fd8..c154a5087c 100755 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1216,11 +1216,11 @@ module ActiveRecord # callbacks will be executed after the association is wiped out. old_method = "destroy_without_habtm_shim_for_#{reflection.name}" class_eval <<-end_eval unless method_defined?(old_method) - alias_method :#{old_method}, :destroy_without_callbacks - def destroy_without_callbacks - #{reflection.name}.clear - #{old_method} - end + alias_method :#{old_method}, :destroy_without_callbacks # alias_method :destroy_without_habtm_shim_for_posts, :destroy_without_callbacks + def destroy_without_callbacks # def destroy_without_callbacks + #{reflection.name}.clear # posts.clear + #{old_method} # destroy_without_habtm_shim_for_posts + end # end end_eval add_association_callbacks(reflection.name, options) @@ -1463,22 +1463,22 @@ module ActiveRecord before_destroy method_name when :delete_all module_eval %Q{ - before_destroy do |record| - delete_all_has_many_dependencies(record, - "#{reflection.name}", - #{reflection.class_name}, - %@#{dependent_conditions}@) - end + before_destroy do |record| # before_destroy do |record| + delete_all_has_many_dependencies(record, # delete_all_has_many_dependencies(record, + "#{reflection.name}", # "posts", + #{reflection.class_name}, # Post, + %@#{dependent_conditions}@) # %@...@) # this is a string literal like %(...) + end # end } when :nullify module_eval %Q{ - before_destroy do |record| - nullify_has_many_dependencies(record, - "#{reflection.name}", - #{reflection.class_name}, - "#{reflection.primary_key_name}", - %@#{dependent_conditions}@) - end + before_destroy do |record| # before_destroy do |record| + nullify_has_many_dependencies(record, # nullify_has_many_dependencies(record, + "#{reflection.name}", # "posts", + #{reflection.class_name}, # Post, + "#{reflection.primary_key_name}", # "user_id", + %@#{dependent_conditions}@) # %@...@) # this is a string literal like %(...) + end # end } else raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, or :nullify (#{reflection.options[:dependent].inspect})" diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 2b3d210fd7..79f3dffe4b 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1820,10 +1820,31 @@ module ActiveRecord #:nodoc: if match.finder? finder = match.finder bang = match.bang? + # def self.find_by_login_and_activated(*args) + # options = args.extract_options! + # attributes = construct_attributes_from_arguments( + # [:login,:activated], + # args + # ) + # finder_options = { :conditions => attributes } + # validate_find_options(options) + # set_readonly_option!(options) + # + # if options[:conditions] + # with_scope(:find => finder_options) do + # find(:first, options) + # end + # else + # find(:first, options.merge(finder_options)) + # end + # end self.class_eval %{ def self.#{method_id}(*args) options = args.extract_options! - attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args) + attributes = construct_attributes_from_arguments( + [:#{attribute_names.join(',:')}], + args + ) finder_options = { :conditions => attributes } validate_find_options(options) set_readonly_option!(options) @@ -1841,6 +1862,31 @@ module ActiveRecord #:nodoc: send(method_id, *arguments) elsif match.instantiator? instantiator = match.instantiator + # def self.find_or_create_by_user_id(*args) + # guard_protected_attributes = false + # + # if args[0].is_a?(Hash) + # guard_protected_attributes = true + # attributes = args[0].with_indifferent_access + # find_attributes = attributes.slice(*[:user_id]) + # else + # find_attributes = attributes = construct_attributes_from_arguments([:user_id], args) + # end + # + # options = { :conditions => find_attributes } + # set_readonly_option!(options) + # + # record = find(:first, options) + # + # if record.nil? + # record = self.new { |r| r.send(:attributes=, attributes, guard_protected_attributes) } + # yield(record) if block_given? + # record.save + # record + # else + # record + # end + # end self.class_eval %{ def self.#{method_id}(*args) guard_protected_attributes = false @@ -2412,9 +2458,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/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb index 950bd72101..00c71090f3 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb @@ -14,12 +14,12 @@ module ActiveRecord def dirties_query_cache(base, *method_names) method_names.each do |method_name| base.class_eval <<-end_code, __FILE__, __LINE__ - def #{method_name}_with_query_dirty(*args) - clear_query_cache if @query_cache_enabled - #{method_name}_without_query_dirty(*args) - end - - alias_method_chain :#{method_name}, :query_dirty + def #{method_name}_with_query_dirty(*args) # def update_with_query_dirty(*args) + clear_query_cache if @query_cache_enabled # clear_query_cache if @query_cache_enabled + #{method_name}_without_query_dirty(*args) # update_without_query_dirty(*args) + end # end + # + alias_method_chain :#{method_name}, :query_dirty # alias_method_chain :update, :query_dirty end_code end end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index fe9cbcf024..273f823e7f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -476,12 +476,12 @@ module ActiveRecord %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type| class_eval <<-EOV - def #{column_type}(*args) - options = args.extract_options! - column_names = args - - column_names.each { |name| column(name, '#{column_type}', options) } - end + def #{column_type}(*args) # def string(*args) + options = args.extract_options! # options = args.extract_options! + column_names = args # column_names = args + # + column_names.each { |name| column(name, '#{column_type}', options) } # column_names.each { |name| column(name, 'string', options) } + end # end EOV end @@ -676,24 +676,24 @@ module ActiveRecord # t.string(:goat, :sheep) %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type| class_eval <<-EOV - def #{column_type}(*args) - options = args.extract_options! - column_names = args - - column_names.each do |name| - column = ColumnDefinition.new(@base, name, '#{column_type}') - if options[:limit] - column.limit = options[:limit] - elsif native['#{column_type}'.to_sym].is_a?(Hash) - column.limit = native['#{column_type}'.to_sym][:limit] - end - column.precision = options[:precision] - column.scale = options[:scale] - column.default = options[:default] - column.null = options[:null] - @base.add_column(@table_name, name, column.sql_type, options) - end - end + def #{column_type}(*args) # def string(*args) + options = args.extract_options! # options = args.extract_options! + column_names = args # column_names = args + # + column_names.each do |name| # column_names.each do |name| + column = ColumnDefinition.new(@base, name, '#{column_type}') # column = ColumnDefinition.new(@base, name, 'string') + if options[:limit] # if options[:limit] + column.limit = options[:limit] # column.limit = options[:limit] + elsif native['#{column_type}'.to_sym].is_a?(Hash) # elsif native['string'.to_sym].is_a?(Hash) + column.limit = native['#{column_type}'.to_sym][:limit] # column.limit = native['string'.to_sym][:limit] + end # end + column.precision = options[:precision] # column.precision = options[:precision] + column.scale = options[:scale] # column.scale = options[:scale] + column.default = options[:default] # column.default = options[:default] + column.null = options[:null] # column.null = options[:null] + @base.add_column(@table_name, name, column.sql_type, options) # @base.add_column(@table_name, name, column.sql_type, options) + end # end + end # end EOV end diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb index 46d4b6c89c..60729c63db 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb @@ -13,23 +13,25 @@ module MysqlCompat #:nodoc: # C driver >= 2.7 returns null values in each_hash if Mysql.const_defined?(:VERSION) && (Mysql::VERSION.is_a?(String) || Mysql::VERSION >= 20700) target.class_eval <<-'end_eval' - def all_hashes - rows = [] - each_hash { |row| rows << row } - rows - end + def all_hashes # def all_hashes + rows = [] # rows = [] + each_hash { |row| rows << row } # each_hash { |row| rows << row } + rows # rows + end # end end_eval # adapters before 2.7 don't have a version constant # and don't return null values in each_hash else target.class_eval <<-'end_eval' - def all_hashes - rows = [] - all_fields = fetch_fields.inject({}) { |fields, f| fields[f.name] = nil; fields } - each_hash { |row| rows << all_fields.dup.update(row) } - rows - end + def all_hashes # def all_hashes + rows = [] # rows = [] + all_fields = fetch_fields.inject({}) { |fields, f| # all_fields = fetch_fields.inject({}) { |fields, f| + fields[f.name] = nil; fields # fields[f.name] = nil; fields + } # } + each_hash { |row| rows << all_fields.dup.update(row) } # each_hash { |row| rows << all_fields.dup.update(row) } + rows # rows + end # end end_eval end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 60ec01b95e..6685cb8663 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -950,13 +950,13 @@ module ActiveRecord # should know about this but can't detect it there, so deal with it here. money_precision = (postgresql_version >= 80300) ? 19 : 10 PostgreSQLColumn.module_eval(<<-end_eval) - def extract_precision(sql_type) - if sql_type =~ /^money$/ - #{money_precision} - else - super - end - end + def extract_precision(sql_type) # def extract_precision(sql_type) + if sql_type =~ /^money$/ # if sql_type =~ /^money$/ + #{money_precision} # 19 + else # else + super # super + end # end + end # end end_eval configure_connection diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index a1760875ba..4c899f58e5 100644 --- a/activerecord/lib/active_record/dirty.rb +++ b/activerecord/lib/active_record/dirty.rb @@ -174,7 +174,7 @@ module ActiveRecord alias_attribute_without_dirty(new_name, old_name) DIRTY_SUFFIXES.each do |suffix| module_eval <<-STR, __FILE__, __LINE__+1 - def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end + def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end # def subject_changed?; self.title_changed?; end STR end end diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index 8c9ae8a031..45e74ea024 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -104,6 +104,14 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase authors.first.posts.first.special_comments.first.post.very_special_comment end end + + def test_eager_association_loading_where_first_level_returns_nil + authors = Author.find(:all, :include => {:post_about_thinking => :comments}, :order => 'authors.id DESC') + assert_equal [authors(:mary), authors(:david)], authors + assert_no_queries do + authors[1].post_about_thinking.comments.first + end + end end require 'models/vertex' diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index a2d0efab92..afbd9fddf9 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -771,4 +771,19 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal author_addresses(:david_address), authors[0].author_address end + def test_preload_belongs_to_uses_exclusive_scope + people = Person.males.find(:all, :include => :primary_contact) + assert_not_equal people.length, 0 + people.each do |person| + assert_no_queries {assert_not_nil person.primary_contact} + assert_equal Person.find(person.id).primary_contact, person.primary_contact + end + end + + def test_preload_has_many_uses_exclusive_scope + people = Person.males.find :all, :include => :agents + people.each do |person| + assert_equal Person.find(person.id).agents, person.agents + end + end end 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/activerecord/test/fixtures/people.yml b/activerecord/test/fixtures/people.yml index d5a69e561d..3babb1fe59 100644 --- a/activerecord/test/fixtures/people.yml +++ b/activerecord/test/fixtures/people.yml @@ -1,6 +1,15 @@ michael: id: 1 first_name: Michael + primary_contact_id: 2 + gender: M david: id: 2 - first_name: David
\ No newline at end of file + first_name: David + primary_contact_id: 3 + gender: M +susan: + id: 3 + first_name: Susan + primary_contact_id: 2 + gender: F
\ No newline at end of file diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb index 430d0b38f7..ec2f684a6e 100644 --- a/activerecord/test/models/person.rb +++ b/activerecord/test/models/person.rb @@ -7,4 +7,10 @@ class Person < ActiveRecord::Base has_many :jobs, :through => :references has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true] has_many :posts_with_comments_sorted_by_comment_id, :through => :readers, :source => :post, :include => :comments, :order => 'comments.id' + + belongs_to :primary_contact, :class_name => 'Person' + has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id' + + named_scope :males, :conditions => { :gender => 'M' } + named_scope :females, :conditions => { :gender => 'F' } end diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index fbacc692b4..8199cb8fc7 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -298,8 +298,10 @@ ActiveRecord::Schema.define do end create_table :people, :force => true do |t| - t.string :first_name, :null => false - t.integer :lock_version, :null => false, :default => 0 + t.string :first_name, :null => false + t.references :primary_contact + t.string :gender, :limit => 1 + t.integer :lock_version, :null => false, :default => 0 end create_table :pets, :primary_key => :pet_id ,:force => true do |t| diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb index 9ed532b48c..0b4549f759 100644 --- a/activeresource/lib/active_resource/http_mock.rb +++ b/activeresource/lib/active_resource/http_mock.rb @@ -54,6 +54,9 @@ module ActiveResource end for method in [ :post, :put, :get, :delete, :head ] + # def post(path, request_headers = {}, body = nil, status = 200, response_headers = {}) + # @responses[Request.new(:post, path, nil, request_headers)] = Response.new(body || "", status, response_headers) + # end module_eval <<-EOE, __FILE__, __LINE__ def #{method}(path, request_headers = {}, body = nil, status = 200, response_headers = {}) @responses[Request.new(:#{method}, path, nil, request_headers)] = Response.new(body || "", status, response_headers) @@ -118,6 +121,11 @@ module ActiveResource end for method in [ :post, :put ] + # def post(path, body, headers) + # request = ActiveResource::Request.new(:post, path, body, headers) + # self.class.requests << request + # self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for #{request}")) + # end module_eval <<-EOE, __FILE__, __LINE__ def #{method}(path, body, headers) request = ActiveResource::Request.new(:#{method}, path, body, headers) diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb index 445d8edf47..33bcf327f8 100644 --- a/activesupport/lib/active_support/buffered_logger.rb +++ b/activesupport/lib/active_support/buffered_logger.rb @@ -68,13 +68,13 @@ module ActiveSupport 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 + 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..992827f7f4 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -210,20 +210,24 @@ module ActiveSupport 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 - - 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}(*methods, &block) # def self.before_save(*methods, &block) + callbacks = CallbackChain.build(:#{callback}, *methods, &block) # callbacks = CallbackChain.build(:before_save, *methods, &block) + @#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new + @#{callback}_callbacks.concat callbacks # @before_save_callbacks.concat callbacks + end # end + # + def self.#{callback}_callback_chain # def self.before_save_callback_chain + @#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new + # + if superclass.respond_to?(:#{callback}_callback_chain) # if superclass.respond_to?(:before_save_callback_chain) + CallbackChain.new( # CallbackChain.new( + superclass.#{callback}_callback_chain + # superclass.before_save_callback_chain + + @#{callback}_callbacks # @before_save_callbacks + ) # ) + else # else + @#{callback}_callbacks # @before_save_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..c795871474 100644 --- a/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb +++ b/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb @@ -11,17 +11,17 @@ class Class syms.flatten.each do |sym| next if sym.is_a?(Hash) class_eval(<<-EOS, __FILE__, __LINE__) - unless defined? @@#{sym} - @@#{sym} = nil - end - - def self.#{sym} - @@#{sym} - end - - def #{sym} - @@#{sym} - end + unless defined? @@#{sym} # unless defined? @@hair_colors + @@#{sym} = nil # @@hair_colors = nil + end # end + # + def self.#{sym} # def self.hair_colors + @@#{sym} # @@hair_colors + end # end + # + def #{sym} # def hair_colors + @@#{sym} # @@hair_colors + end # end EOS end end @@ -30,19 +30,19 @@ class Class 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 - " unless options[:instance_writer] == false } + unless defined? @@#{sym} # unless defined? @@hair_colors + @@#{sym} = nil # @@hair_colors = nil + end # end + # + def self.#{sym}=(obj) # def self.hair_colors=(obj) + @@#{sym} = obj # @@hair_colors = obj + end # end + # + #{" # + def #{sym}=(obj) # def hair_colors=(obj) + @@#{sym} = obj # @@hair_colors = obj + end # end + " unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false EOS end 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..000ccf4d55 100644 --- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb @@ -9,22 +9,23 @@ class Class 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 + def self.#{name} # def self.only_reader + if defined?(@#{name}) # if defined?(@only_reader) + @#{name} # @only_reader + elsif superclass < #{class_name_to_stop_searching_on} && # elsif superclass < Object && + superclass.respond_to?(:#{name}) # superclass.respond_to?(:only_reader) + superclass.#{name} # superclass.only_reader + end # end + end # end + def #{name} # def only_reader + self.class.#{name} # self.class.only_reader + end # end + def self.#{name}? # def self.only_reader? + !!#{name} # !!only_reader + end # end + def #{name}? # def only_reader? + !!#{name} # !!only_reader + end # end EOS end end @@ -32,9 +33,9 @@ class Class def superclass_delegating_writer(*names) names.each do |name| class_eval <<-EOS - def self.#{name}=(value) - @#{name} = value - end + def self.#{name}=(value) # def self.only_writer=(value) + @#{name} = value # @only_writer = 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..1794afe77c 100644 --- a/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb +++ b/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb @@ -11,13 +11,13 @@ class Class # :nodoc: 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 + def self.#{sym} # def self.before_add_for_comments + read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:before_add_for_comments) + end # end + # + def #{sym} # def before_add_for_comments + self.class.#{sym} # self.class.before_add_for_comments + end # end EOS end end @@ -26,15 +26,15 @@ class Class # :nodoc: options = syms.extract_options! syms.each do |sym| class_eval <<-EOS - def self.#{sym}=(obj) - write_inheritable_attribute(:#{sym}, obj) - end - - #{" - def #{sym}=(obj) - self.class.#{sym} = obj - end - " unless options[:instance_writer] == false } + def self.#{sym}=(obj) # def self.color=(obj) + write_inheritable_attribute(:#{sym}, obj) # write_inheritable_attribute(:color, obj) + end # end + # + #{" # + def #{sym}=(obj) # def color=(obj) + self.class.#{sym} = obj # self.class.color = obj + end # end + " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false EOS end end @@ -43,15 +43,15 @@ class Class # :nodoc: options = syms.extract_options! syms.each do |sym| class_eval <<-EOS - def self.#{sym}=(obj) - write_inheritable_array(:#{sym}, obj) - end - - #{" - def #{sym}=(obj) - self.class.#{sym} = obj - end - " unless options[:instance_writer] == false } + def self.#{sym}=(obj) # def self.levels=(obj) + write_inheritable_array(:#{sym}, obj) # write_inheritable_array(:levels, obj) + end # end + # + #{" # + def #{sym}=(obj) # def levels=(obj) + self.class.#{sym} = obj # self.class.levels = obj + end # end + " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false EOS end end @@ -60,15 +60,15 @@ class Class # :nodoc: options = syms.extract_options! syms.each do |sym| class_eval <<-EOS - def self.#{sym}=(obj) - write_inheritable_hash(:#{sym}, obj) - end - - #{" - def #{sym}=(obj) - self.class.#{sym} = obj - end - " unless options[:instance_writer] == false } + def self.#{sym}=(obj) # def self.nicknames=(obj) + write_inheritable_hash(:#{sym}, obj) # write_inheritable_hash(:nicknames, obj) + end # end + # + #{" # + def #{sym}=(obj) # def nicknames=(obj) + self.class.#{sym} = obj # self.class.nicknames = obj + end # end + " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false EOS end end diff --git a/activesupport/lib/active_support/core_ext/hash/slice.rb b/activesupport/lib/active_support/core_ext/hash/slice.rb index 88df49a69f..d845a6d8ca 100644 --- a/activesupport/lib/active_support/core_ext/hash/slice.rb +++ b/activesupport/lib/active_support/core_ext/hash/slice.rb @@ -24,10 +24,17 @@ module ActiveSupport #:nodoc: end # Replaces the hash with only the given keys. + # Returns a hash contained the removed key/value pairs + # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d =>4} def slice!(*keys) - replace(slice(*keys)) + keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key) + omit = slice(*self.keys - keys) + hash = slice(*keys) + replace(hash) + omit end end end end end + diff --git a/activesupport/lib/active_support/core_ext/logger.rb b/activesupport/lib/active_support/core_ext/logger.rb index 24fe7294c9..858da7aa07 100644 --- a/activesupport/lib/active_support/core_ext/logger.rb +++ b/activesupport/lib/active_support/core_ext/logger.rb @@ -3,12 +3,12 @@ class Logger def self.define_around_helper(level) module_eval <<-end_eval - def around_#{level}(before_message, after_message, &block) - self.#{level}(before_message) - return_value = block.call(self) - self.#{level}(after_message) - return return_value - end + def around_#{level}(before_message, after_message, &block) # def around_debug(before_message, after_message, &block) + self.#{level}(before_message) # self.debug(before_message) + return_value = block.call(self) # return_value = block.call(self) + self.#{level}(after_message) # self.debug(after_message) + return return_value # return return_value + end # end end_eval end [:debug, :info, :error, :fatal].each {|level| define_around_helper(level) } diff --git a/activesupport/lib/active_support/core_ext/module/aliasing.rb b/activesupport/lib/active_support/core_ext/module/aliasing.rb index e640f64520..10fa520ba1 100644 --- a/activesupport/lib/active_support/core_ext/module/aliasing.rb +++ b/activesupport/lib/active_support/core_ext/module/aliasing.rb @@ -64,9 +64,9 @@ module ActiveSupport # e.title # => "Megastars" def alias_attribute(new_name, old_name) module_eval <<-STR, __FILE__, __LINE__+1 - def #{new_name}; self.#{old_name}; end - def #{new_name}?; self.#{old_name}?; end - def #{new_name}=(v); self.#{old_name} = v; end + def #{new_name}; self.#{old_name}; end # def subject; self.title; end + def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end + def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end STR end end diff --git a/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb b/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb index 683789d853..4d0198f028 100644 --- a/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb +++ b/activesupport/lib/active_support/core_ext/module/attr_accessor_with_default.rb @@ -22,10 +22,10 @@ class Module raise 'Default value or block required' unless !default.nil? || block define_method(sym, block_given? ? block : Proc.new { default }) module_eval(<<-EVAL, __FILE__, __LINE__) - def #{sym}=(value) - class << self; attr_reader :#{sym} end - @#{sym} = value - end + def #{sym}=(value) # def age=(value) + class << self; attr_reader :#{sym} end # class << self; attr_reader :age end + @#{sym} = value # @age = value + end # end EVAL end 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..9402cb8534 100644 --- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb @@ -15,17 +15,17 @@ class Module syms.each do |sym| next if sym.is_a?(Hash) class_eval(<<-EOS, __FILE__, __LINE__) - unless defined? @@#{sym} - @@#{sym} = nil - end - - def self.#{sym} - @@#{sym} - end - - def #{sym} - @@#{sym} - end + unless defined? @@#{sym} # unless defined? @@pagination_options + @@#{sym} = nil # @@pagination_options = nil + end # end + # + def self.#{sym} # def self.pagination_options + @@#{sym} # @@pagination_options + end # end + # + def #{sym} # def pagination_options + @@#{sym} # @@pagination_options + end # end EOS end end @@ -34,19 +34,19 @@ class Module 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 - " unless options[:instance_writer] == false } + unless defined? @@#{sym} # unless defined? @@pagination_options + @@#{sym} = nil # @@pagination_options = nil + end # end + # + def self.#{sym}=(obj) # def self.pagination_options=(obj) + @@#{sym} = obj # @@pagination_options = obj + end # end + # + #{" # + def #{sym}=(obj) # def pagination_options=(obj) + @@#{sym} = obj # @@pagination_options = obj + end # end + " unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false EOS end end diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 5c75bd4938..fb4b5f0f3c 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -112,9 +112,9 @@ class Module methods.each do |method| module_eval(<<-EOS, "(__DELEGATION__)", 1) - def #{prefix}#{method}(*args, &block) - #{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block) - end + def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block) + #{allow_nil}#{to}.__send__(#{method.inspect}, *args, &block) # client && client.__send__(:name, *args, &block) + end # end EOS end end diff --git a/activesupport/lib/active_support/core_ext/module/synchronization.rb b/activesupport/lib/active_support/core_ext/module/synchronization.rb index 251606024e..069db3fed0 100644 --- a/activesupport/lib/active_support/core_ext/module/synchronization.rb +++ b/activesupport/lib/active_support/core_ext/module/synchronization.rb @@ -26,11 +26,11 @@ class Module end module_eval(<<-EOS, __FILE__, __LINE__) - def #{aliased_method}_with_synchronization#{punctuation}(*args, &block) - #{with}.synchronize do - #{aliased_method}_without_synchronization#{punctuation}(*args, &block) - end - end + def #{aliased_method}_with_synchronization#{punctuation}(*args, &block) # def expire_with_synchronization(*args, &block) + #{with}.synchronize do # @@lock.synchronize do + #{aliased_method}_without_synchronization#{punctuation}(*args, &block) # expire_without_synchronization(*args, &block) + end # end + end # end EOS alias_method_chain method, :synchronization diff --git a/activesupport/lib/active_support/deprecation.rb b/activesupport/lib/active_support/deprecation.rb index 25b26e9c96..d20151661b 100644 --- a/activesupport/lib/active_support/deprecation.rb +++ b/activesupport/lib/active_support/deprecation.rb @@ -90,10 +90,15 @@ module ActiveSupport 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 + def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block) + ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn( + self.class.deprecated_method_warning( # self.class.deprecated_method_warning( + :#{method_name}, # :generate_secret, + #{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"), + caller # caller + ) # ) + #{target}_without_deprecation#{punctuation}(*args, &block) # generate_secret_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..952b4d8063 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -59,34 +59,36 @@ module ActiveSupport memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol) class_eval <<-EOS, __FILE__, __LINE__ - include InstanceMethods - - raise "Already memoized #{symbol}" if method_defined?(:#{original_method}) - alias #{original_method} #{symbol} - - 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 + include InstanceMethods # include InstanceMethods + # + if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type) + raise "Already memoized #{symbol}" # raise "Already memoized mime_type" + end # end + alias #{original_method} #{symbol} # alias _unmemoized_mime_type mime_type + # + if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0 + def #{symbol}(reload = false) # def mime_type(reload = false) + if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty? + #{memoized_ivar} = [#{original_method}.freeze] # @_memoized_mime_type = [_unmemoized_mime_type.freeze] + end # end + #{memoized_ivar}[0] # @_memoized_mime_type[0] + end # end + else # else + def #{symbol}(*args) # def mime_type(*args) + #{memoized_ivar} ||= {} unless frozen? # @_memoized_mime_type ||= {} 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_mime_type) && @_memoized_mime_type + if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args) + #{memoized_ivar}[args] # @_memoized_mime_type[args] + elsif #{memoized_ivar} # elsif @_memoized_mime_type + #{memoized_ivar}[args] = #{original_method}(*args).freeze # @_memoized_mime_type[args] = _unmemoized_mime_type(*args).freeze + end # end + else # else + #{original_method}(*args) # _unmemoized_mime_type(*args) + end # end + end # end + end # end EOS end end diff --git a/activesupport/lib/active_support/multibyte/unicode_database.rb b/activesupport/lib/active_support/multibyte/unicode_database.rb index 3b8cf8f9eb..a08f38cdbb 100644 --- a/activesupport/lib/active_support/multibyte/unicode_database.rb +++ b/activesupport/lib/active_support/multibyte/unicode_database.rb @@ -24,10 +24,10 @@ 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 + 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..72ff684fcc 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -234,9 +234,9 @@ module ActiveSupport %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 + def #{method_name} # def year + time.#{method_name} # time.year + end # end EOV end diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb index 63ccb5a7da..b63ab30965 100644 --- a/activesupport/test/core_ext/hash_ext_test.rb +++ b/activesupport/test/core_ext/hash_ext_test.rb @@ -287,10 +287,14 @@ class HashExtTest < Test::Unit::TestCase # Should return a new hash with only the given keys. assert_equal expected, original.slice(:a, :b) assert_not_equal expected, original + end + + def test_slice_inplace + original = { :a => 'x', :b => 'y', :c => 10 } + expected = { :c => 10 } # Should replace the hash with only the given keys. assert_equal expected, original.slice!(:a, :b) - assert_equal expected, original end def test_slice_with_an_array_key @@ -300,10 +304,14 @@ class HashExtTest < Test::Unit::TestCase # Should return a new hash with only the given keys when given an array key. assert_equal expected, original.slice([:a, :b], :c) assert_not_equal expected, original + end + + def test_slice_inplace_with_an_array_key + original = { :a => 'x', :b => 'y', :c => 10, [:a, :b] => "an array key" } + expected = { :a => 'x', :b => 'y' } # Should replace the hash with only the given keys when given an array key. assert_equal expected, original.slice!([:a, :b], :c) - assert_equal expected, original end def test_slice_with_splatted_keys @@ -322,11 +330,17 @@ class HashExtTest < Test::Unit::TestCase # Should return a new hash with only the given keys. assert_equal expected, original.slice(*keys), keys.inspect assert_not_equal expected, original + end + end + def test_indifferent_slice_inplace + original = { :a => 'x', :b => 'y', :c => 10 }.with_indifferent_access + expected = { :c => 10 }.with_indifferent_access + + [['a', 'b'], [:a, :b]].each do |keys| # Should replace the hash with only the given keys. copy = original.dup assert_equal expected, copy.slice!(*keys) - assert_equal expected, copy end 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 1e0c6cc3ff..84e36ecc1b 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,28 +75,36 @@ 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? - opts = options.inject([]) {|result, h| result << [":#{h[0]} => '#{h[1]}'"] }.join(", ") + opts = options.inject([]) {|result, h| result << [":#{h[0]} => '#{h[1]}'"] }.sort.join(", ") 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 @@ -374,5 +353,23 @@ 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 + + def logger + @logger ||= if defined?(Rails::Generator::Base) + Rails::Generator::Base.logger + else + require 'rails_generator/simple_logger' + Rails::Generator::SimpleLogger.new(STDOUT) + end + end + end end 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..fcc020603d --- /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', :lib => 'will-paginate', :source => 'http://gems.github.com'") + 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 |