diff options
68 files changed, 493 insertions, 972 deletions
diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000000..4f89247bbb --- /dev/null +++ b/.yardopts @@ -0,0 +1,3 @@ +--exclude /templates/ +--quiet +act*/lib/**/*.rb @@ -144,6 +144,7 @@ task :rdoc do FileUtils.copy "activerecord/examples/associations.png", "doc/rdoc/files/examples/associations.png" end +desc 'Bump all versions to match version.rb' task :update_versions do require File.dirname(__FILE__) + "/version" diff --git a/actionmailer/CHANGELOG b/actionmailer/CHANGELOG index d2cc70fc85..62c1402346 100644 --- a/actionmailer/CHANGELOG +++ b/actionmailer/CHANGELOG @@ -1,9 +1,9 @@ -*Rails 3.0.0 [release candidate] (July 26th, 2010)* +*Rails 3.1.0 (unreleased)* -* No material changes +* No changes -*Rails 3.0.0 [beta 4] (June 8th, 2010)* +*Rails 3.0.0 (August 29, 2010)* * subject is automatically looked up on I18n using mailer_name and action_name as scope as in t(".subject") [JK] @@ -11,16 +11,10 @@ * Added ability to pass Proc objects to the defaults hash [ML] - -*Rails 3.0.0 [beta 3] (April 13th, 2010)* - * Removed all quoting.rb type files from ActionMailer and put Mail 2.2.0 in instead [ML] * Lot of updates to various test cases that now work better with the new Mail and so have different expectations - -*Rails 3.0.0 [beta 2] (April 1st, 2010)* - * Added interceptors and observers from Mail [ML] ActionMailer::Base.register_interceptor calls Mail.register_interceptor @@ -38,9 +32,6 @@ * Whole new API added with tests. See base.rb for full details. Old API is deprecated. - -*Rails 3.0.0 [beta 1] (February 4, 2010)* - * The Mail::Message class has helped methods for all the field types that return 'common' defaults for the common use case, so to get the subject, mail.subject will give you a string, mail.date will give you a DateTime object, mail.from will give you an array of address specs (mikel@test.lindsaar.net) etc. If you want to access the field object itself, call mail[:field_name] which will return the field object you want, which you can then chain, like mail[:from].formatted * Mail#content_type now returns the content_type field as a string. If you want the mime type of a mail, then you call Mail#mime_type (eg, text/plain), if you want the parameters of the content type field, you call Mail#content_type_parameters which gives you a hash, eg {'format' => 'flowed', 'charset' => 'utf-8'} diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 6e2d288082..05ba12197a 100644 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -43,7 +43,6 @@ module ActionMailer autoload :Collector autoload :Base autoload :DeliveryMethods - autoload :DeprecatedApi autoload :MailHelper autoload :OldApi autoload :TestCase diff --git a/actionmailer/lib/action_mailer/adv_attr_accessor.rb b/actionmailer/lib/action_mailer/adv_attr_accessor.rb index be6b1feca9..c1aa8021ce 100644 --- a/actionmailer/lib/action_mailer/adv_attr_accessor.rb +++ b/actionmailer/lib/action_mailer/adv_attr_accessor.rb @@ -1,26 +1,28 @@ module ActionMailer module AdvAttrAccessor #:nodoc: - def adv_attr_accessor(*names) - names.each do |name| - ivar = "@#{name}" + def adv_attr_accessor(name, deprecation=nil) + ivar = "@#{name}" + deprecation ||= "Please pass :#{name} as hash key to mail() instead" - class_eval <<-ACCESSORS, __FILE__, __LINE__ + 1 - def #{name}=(value) - #{ivar} = value - end + class_eval <<-ACCESSORS, __FILE__, __LINE__ + 1 + def #{name}=(value) + ActiveSupport::Deprecation.warn "#{name}= is deprecated. #{deprecation}" + #{ivar} = value + end - def #{name}(*args) - raise ArgumentError, "expected 0 or 1 parameters" unless args.length <= 1 - if args.empty? - #{ivar} if instance_variable_names.include?(#{ivar.inspect}) - else - #{ivar} = args.first - end + def #{name}(*args) + raise ArgumentError, "expected 0 or 1 parameters" unless args.length <= 1 + if args.empty? + ActiveSupport::Deprecation.warn "#{name}() is deprecated and will be removed in future versions." + #{ivar} if instance_variable_names.include?(#{ivar.inspect}) + else + ActiveSupport::Deprecation.warn "#{name}(value) is deprecated. #{deprecation}" + #{ivar} = args.first end - ACCESSORS + end + ACCESSORS - self.protected_instance_variables << ivar if self.respond_to?(:protected_instance_variables) - end + self.protected_instance_variables << ivar if self.respond_to?(:protected_instance_variables) end end end diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 8fe5868d52..31e1b26afd 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -341,10 +341,11 @@ module ActionMailer #:nodoc: include AbstractController::Translation include AbstractController::AssetPaths - helper ActionMailer::MailHelper + cattr_reader :protected_instance_variables + @@protected_instance_variables = [] + helper ActionMailer::MailHelper include ActionMailer::OldApi - include ActionMailer::DeprecatedApi delegate :register_observer, :to => Mail delegate :register_interceptor, :to => Mail @@ -446,6 +447,10 @@ module ActionMailer #:nodoc: super end + def mailer_name + self.class.mailer_name + end + # Allows you to pass random and unusual headers to the new +Mail::Message+ object # which will add them to itself. # diff --git a/actionmailer/lib/action_mailer/deprecated_api.rb b/actionmailer/lib/action_mailer/deprecated_api.rb deleted file mode 100644 index 7d57feba04..0000000000 --- a/actionmailer/lib/action_mailer/deprecated_api.rb +++ /dev/null @@ -1,141 +0,0 @@ -require 'active_support/core_ext/object/try' - -module ActionMailer - # This is the API which is deprecated and is going to be removed on Rails 3.1 release. - # Part of the old API will be deprecated after 3.1, for a smoother deprecation process. - # Check those in OldApi instead. - module DeprecatedApi #:nodoc: - extend ActiveSupport::Concern - - included do - [:charset, :content_type, :mime_version, :implicit_parts_order].each do |method| - class_eval <<-FILE, __FILE__, __LINE__ + 1 - def self.default_#{method} - @@default_#{method} - end - - def self.default_#{method}=(value) - ActiveSupport::Deprecation.warn "ActionMailer::Base.default_#{method}=value is deprecated, " << - "use default :#{method} => value instead" - @@default_#{method} = value - end - - @@default_#{method} = nil - FILE - end - end - - module ClassMethods - # Deliver the given mail object directly. This can be used to deliver - # a preconstructed mail object, like: - # - # email = MyMailer.create_some_mail(parameters) - # email.set_some_obscure_header "frobnicate" - # MyMailer.deliver(email) - def deliver(mail, show_warning=true) - if show_warning - ActiveSupport::Deprecation.warn "#{self}.deliver is deprecated, call " << - "deliver in the mailer instance instead", caller[0,2] - end - - raise "no mail object available for delivery!" unless mail - wrap_delivery_behavior(mail) - mail.deliver - mail - end - - def template_root - self.view_paths && self.view_paths.first - end - - def template_root=(root) - ActiveSupport::Deprecation.warn "template_root= is deprecated, use prepend_view_path instead", caller[0,2] - self.view_paths = ActionView::Base.process_view_paths(root) - end - - def respond_to?(method_symbol, include_private = false) - matches_dynamic_method?(method_symbol) || super - end - - def method_missing(method_symbol, *parameters) - if match = matches_dynamic_method?(method_symbol) - case match[1] - when 'create' - ActiveSupport::Deprecation.warn "#{self}.create_#{match[2]} is deprecated, " << - "use #{self}.#{match[2]} instead", caller[0,2] - new(match[2], *parameters).message - when 'deliver' - ActiveSupport::Deprecation.warn "#{self}.deliver_#{match[2]} is deprecated, " << - "use #{self}.#{match[2]}.deliver instead", caller[0,2] - new(match[2], *parameters).message.deliver - else super - end - else - super - end - end - - private - - def matches_dynamic_method?(method_name) - method_name = method_name.to_s - /^(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name) - end - end - - # Delivers a Mail object. By default, it delivers the cached mail - # object (from the <tt>create!</tt> method). If no cached mail object exists, and - # no alternate has been given as the parameter, this will fail. - def deliver!(mail = @_message) - ActiveSupport::Deprecation.warn "Calling deliver in the AM::Base object is deprecated, " << - "please call deliver in the Mail instance", caller[0,2] - self.class.deliver(mail, false) - end - alias :deliver :deliver! - - def render(*args) - options = args.last.is_a?(Hash) ? args.last : {} - - if options[:body].is_a?(Hash) - ActiveSupport::Deprecation.warn(':body in render deprecated. Please use instance ' << - 'variables as assigns instead', caller[0,1]) - - options[:body].each { |k,v| instance_variable_set(:"@#{k}", v) } - end - super - end - - # Render a message but does not set it as mail body. Useful for rendering - # data for part and attachments. - # - # Examples: - # - # render_message "special_message" - # render_message :template => "special_message" - # render_message :inline => "<%= 'Hi!' %>" - # - def render_message(*args) - ActiveSupport::Deprecation.warn "render_message is deprecated, use render instead", caller[0,2] - render(*args) - end - - private - - def initialize_defaults(*) - @charset ||= self.class.default_charset.try(:dup) - @content_type ||= self.class.default_content_type.try(:dup) - @implicit_parts_order ||= self.class.default_implicit_parts_order.try(:dup) - @mime_version ||= self.class.default_mime_version.try(:dup) - super - end - - def create_parts - if @body.is_a?(Hash) && !@body.empty? - ActiveSupport::Deprecation.warn "Giving a hash to body is deprecated, please use instance variables instead", caller[0,2] - @body.each { |k, v| instance_variable_set(:"@#{k}", v) } - end - super - end - - end -end diff --git a/actionmailer/lib/action_mailer/old_api.rb b/actionmailer/lib/action_mailer/old_api.rb index 2a6289c22d..b8c15df263 100644 --- a/actionmailer/lib/action_mailer/old_api.rb +++ b/actionmailer/lib/action_mailer/old_api.rb @@ -8,9 +8,7 @@ module ActionMailer included do extend ActionMailer::AdvAttrAccessor - - @@protected_instance_variables = %w(@parts) - cattr_reader :protected_instance_variables + self.protected_instance_variables.concat %w(@parts @mail_was_called) # Specify the BCC addresses for the message adv_attr_accessor :bcc @@ -42,11 +40,11 @@ module ActionMailer # The recipient addresses for the message, either as a string (for a single # address) or an array (for multiple addresses). - adv_attr_accessor :recipients + adv_attr_accessor :recipients, "Please pass :to as hash key to mail() instead" # The date on which the message was sent. If not set (the default), the # header will be set by the delivery agent. - adv_attr_accessor :sent_on + adv_attr_accessor :sent_on, "Please pass :date as hash key to mail() instead" # Specify the subject of the message. adv_attr_accessor :subject @@ -54,20 +52,12 @@ module ActionMailer # Specify the template name to use for current message. This is the "base" # template name, without the extension or directory, and may be used to # have multiple mailer methods share the same template. - adv_attr_accessor :template - - # Override the mailer name, which defaults to an inflected version of the - # mailer's class name. If you want to use a template in a non-standard - # location, you can use this to specify that location. - adv_attr_accessor :mailer_name + adv_attr_accessor :template, "Please pass :template_name or :template_path as hash key to mail() instead" # Define the body of the message. This is either a Hash (in which case it # specifies the variables to pass to the template when it is rendered), # or a string, in which case it specifies the actual text of the message. adv_attr_accessor :body - - # Alias controller_path to mailer_name so render :partial in views work. - alias :controller_path :mailer_name end def process(method_name, *args) @@ -84,6 +74,8 @@ module ActionMailer # part itself is yielded to the block so that other properties (charset, # body, headers, etc.) can be set on it. def part(params) + ActiveSupport::Deprecation.warn "part() is deprecated and will be removed in future versions. " << + "Please pass a block to mail() instead." params = {:content_type => params} if String === params if custom_headers = params.delete(:headers) @@ -99,6 +91,8 @@ module ActionMailer # Add an attachment to a multipart message. This is simply a part with the # content-disposition set to "attachment". def attachment(params, &block) + ActiveSupport::Deprecation.warn "attachment() is deprecated and will be removed in future versions. " << + "Please use the attachments[] API instead." params = { :content_type => params } if String === params params[:content] ||= params.delete(:data) || params.delete(:body) @@ -148,11 +142,11 @@ module ActionMailer def create_mail m = @_message - set_fields!({:subject => subject, :to => recipients, :from => from, - :bcc => bcc, :cc => cc, :reply_to => reply_to}, charset) + set_fields!({:subject => @subject, :to => @recipients, :from => @from, + :bcc => @bcc, :cc => @cc, :reply_to => @reply_to}, @charset) - m.mime_version = mime_version unless mime_version.nil? - m.date = sent_on.to_time rescue sent_on if sent_on + m.mime_version = @mime_version if @mime_version + m.date = @sent_on.to_time rescue @sent_on if @sent_on @headers.each { |k, v| m[k] = v } @@ -191,6 +185,8 @@ module ActionMailer @implicit_parts_order ||= self.class.default[:parts_order].try(:dup) @mime_version ||= self.class.default[:mime_version].try(:dup) + @cc, @bcc, @reply_to, @subject, @from, @recipients = nil, nil, nil, nil, nil, nil + @mailer_name ||= self.class.mailer_name.dup @template ||= method_name @mail_was_called = false diff --git a/actionmailer/test/abstract_unit.rb b/actionmailer/test/abstract_unit.rb index b430dffdf8..0dce0ac15d 100644 --- a/actionmailer/test/abstract_unit.rb +++ b/actionmailer/test/abstract_unit.rb @@ -78,3 +78,5 @@ end def restore_delivery_method ActionMailer::Base.delivery_method = @old_delivery_method end + +ActiveSupport::Deprecation.silenced = true
\ No newline at end of file diff --git a/actionmailer/test/old_base/asset_host_test.rb b/actionmailer/test/asset_host_test.rb index cc13c8a4d7..069860ff06 100644 --- a/actionmailer/test/old_base/asset_host_test.rb +++ b/actionmailer/test/asset_host_test.rb @@ -3,9 +3,9 @@ require 'action_controller' class AssetHostMailer < ActionMailer::Base def email_with_asset - recipients 'test@localhost' - subject "testing email containing asset path while asset_host is set" - from "tester@example.com" + mail :to => 'test@localhost', + :subject => 'testing email containing asset path while asset_host is set', + :from => 'tester@example.com' end end diff --git a/actionmailer/test/base_test.rb b/actionmailer/test/base_test.rb index c11081072d..7ed9d4a5c0 100644 --- a/actionmailer/test/base_test.rb +++ b/actionmailer/test/base_test.rb @@ -7,9 +7,6 @@ require 'mailers/proc_mailer' require 'mailers/asset_mailer' class BaseTest < ActiveSupport::TestCase - # TODO Add some tests for implicity layout render and url helpers - # so we can get rid of old base tests altogether with old base. - def teardown ActionMailer::Base.asset_host = nil ActionMailer::Base.assets_dir = nil diff --git a/actionmailer/test/old_base/mail_layout_test.rb b/actionmailer/test/mail_layout_test.rb index 2c2daa0f28..def8da81b8 100644 --- a/actionmailer/test/old_base/mail_layout_test.rb +++ b/actionmailer/test/mail_layout_test.rb @@ -1,53 +1,45 @@ require 'abstract_unit' class AutoLayoutMailer < ActionMailer::Base + default :to => 'test@localhost', + :subject => "You have a mail", + :from => "tester@example.com" def hello - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" + mail() end def spam - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - @world = "Earth" - body render(:inline => "Hello, <%= @world %>", :layout => 'spam') + mail(:body => render(:inline => "Hello, <%= @world %>", :layout => 'spam')) end def nolayout - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - @world = "Earth" - body render(:inline => "Hello, <%= @world %>", :layout => false) + mail(:body => render(:inline => "Hello, <%= @world %>", :layout => false)) end def multipart(type = nil) - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" - - content_type(type) if type + mail(:content_type => type) do |format| + format.text { render } + format.html { render } + end end end class ExplicitLayoutMailer < ActionMailer::Base layout 'spam', :except => [:logout] + default :to => 'test@localhost', + :subject => "You have a mail", + :from => "tester@example.com" + def signup - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" + mail() end def logout - recipients 'test@localhost' - subject "You have a mail" - from "tester@example.com" + mail() end end @@ -91,19 +83,6 @@ class LayoutMailerTest < Test::Unit::TestCase assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s end - def test_should_fix_multipart_layout - mail = AutoLayoutMailer.multipart("text/plain") - assert_equal "multipart/alternative", mail.mime_type - assert_equal 2, mail.parts.size - - assert_equal 'text/plain', mail.parts.first.mime_type - assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body.to_s - - assert_equal 'text/html', mail.parts.last.mime_type - assert_equal "Hello from layout text/html multipart", mail.parts.last.body.to_s - end - - def test_should_pickup_layout_given_to_render mail = AutoLayoutMailer.spam assert_equal "Spammer layout Hello, Earth", mail.body.to_s.strip diff --git a/actionmailer/test/mailers/base_mailer.rb b/actionmailer/test/mailers/base_mailer.rb index e89a5820cc..9416bc718e 100644 --- a/actionmailer/test/mailers/base_mailer.rb +++ b/actionmailer/test/mailers/base_mailer.rb @@ -113,6 +113,6 @@ class BaseMailer < ActionMailer::Base end def email_with_translations - body render("email_with_translations.html") + mail :body => render("email_with_translations.html") end end diff --git a/actionmailer/test/old_base/adv_attr_test.rb b/actionmailer/test/old_base/adv_attr_test.rb index f22d733bc5..c5a6b6d88b 100644 --- a/actionmailer/test/old_base/adv_attr_test.rb +++ b/actionmailer/test/old_base/adv_attr_test.rb @@ -11,9 +11,14 @@ class AdvAttrTest < ActiveSupport::TestCase end def setup + ActiveSupport::Deprecation.silenced = true @person = Person.new end + def teardown + ActiveSupport::Deprecation.silenced = false + end + def test_adv_attr assert_nil @person.name @person.name 'Bob' diff --git a/actionmailer/test/old_base/mail_render_test.rb b/actionmailer/test/old_base/mail_render_test.rb index bf489e77d4..3a1d3184f4 100644 --- a/actionmailer/test/old_base/mail_render_test.rb +++ b/actionmailer/test/old_base/mail_render_test.rb @@ -19,18 +19,6 @@ class RenderMailer < ActionMailer::Base body render(:file => "templates/signed_up") end - def rxml_template - recipients 'test@localhost' - subject "rendering rxml template" - from "tester@example.com" - end - - def included_subtemplate - recipients 'test@localhost' - subject "Including another template in the one being rendered" - from "tester@example.com" - end - def no_instance_variable recipients 'test@localhost' subject "No Instance Variable" @@ -41,11 +29,6 @@ class RenderMailer < ActionMailer::Base end end - def initialize_defaults(method_name) - super - mailer_name "test_mailer" - end - def multipart_alternative recipients 'test@localhost' subject 'multipart/alternative' @@ -97,11 +80,13 @@ class RenderHelperTest < Test::Unit::TestCase set_delivery_method :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries.clear + ActiveSupport::Deprecation.silenced = true @recipient = 'test@localhost' end def teardown + ActiveSupport::Deprecation.silenced = false restore_delivery_method end @@ -115,35 +100,16 @@ class RenderHelperTest < Test::Unit::TestCase assert_equal "Hello there,\n\nMr. test@localhost", mail.body.to_s.strip end - def test_rxml_template - mail = RenderMailer.rxml_template.deliver - assert_equal %(<?xml version="1.0" encoding="UTF-8"?>\n<test/>), mail.body.to_s.strip - end - - def test_included_subtemplate - mail = RenderMailer.included_subtemplate.deliver - assert_equal "Hey Ho, let's go!", mail.body.to_s.strip - end - def test_no_instance_variable mail = RenderMailer.no_instance_variable.deliver assert_equal "Look, subject.nil? is true!", mail.body.to_s.strip end - - def test_legacy_multipart_alternative - mail = RenderMailer.multipart_alternative.deliver - assert_equal(2, mail.parts.size) - assert_equal("multipart/alternative", mail.mime_type) - assert_equal("text/plain", mail.parts[0].mime_type) - assert_equal("foo: bar", mail.parts[0].body.encoded) - assert_equal("text/html", mail.parts[1].mime_type) - assert_equal("<strong>foo</strong> bar", mail.parts[1].body.encoded) - end end class FirstSecondHelperTest < Test::Unit::TestCase def setup set_delivery_method :test + ActiveSupport::Deprecation.silenced = true ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries.clear @@ -151,6 +117,7 @@ class FirstSecondHelperTest < Test::Unit::TestCase end def teardown + ActiveSupport::Deprecation.silenced = false restore_delivery_method end diff --git a/actionmailer/test/old_base/mail_service_test.rb b/actionmailer/test/old_base/mail_service_test.rb index a216b94a55..93921978b6 100644 --- a/actionmailer/test/old_base/mail_service_test.rb +++ b/actionmailer/test/old_base/mail_service_test.rb @@ -334,6 +334,7 @@ class ActionMailerTest < Test::Unit::TestCase ActionMailer::Base.perform_deliveries = true ActionMailer::Base.raise_delivery_errors = true ActionMailer::Base.deliveries.clear + ActiveSupport::Deprecation.silenced = true @original_logger = TestMailer.logger @recipient = 'test@localhost' @@ -343,6 +344,7 @@ class ActionMailerTest < Test::Unit::TestCase def teardown TestMailer.logger = @original_logger + ActiveSupport::Deprecation.silenced = false restore_delivery_method end @@ -1095,112 +1097,4 @@ EOF ensure TestMailer.smtp_settings.merge!(:enable_starttls_auto => true) end -end - -class InheritableTemplateRootTest < ActiveSupport::TestCase - def test_attr - expected = File.expand_path("#{File.dirname(__FILE__)}/../fixtures/path.with.dots") - assert_equal expected, FunkyPathMailer.template_root.to_s - - sub = Class.new(FunkyPathMailer) - assert_deprecated do - sub.template_root = 'test/path' - end - - assert_equal File.expand_path('test/path'), sub.template_root.to_s - assert_equal expected, FunkyPathMailer.template_root.to_s - end -end - -class MethodNamingTest < ActiveSupport::TestCase - include ActionMailer::TestHelper - - class TestMailer < ActionMailer::Base - def send - body 'foo' - end - end - - def setup - set_delivery_method :test - ActionMailer::Base.perform_deliveries = true - ActionMailer::Base.deliveries.clear - end - - def teardown - restore_delivery_method - end - - def test_send_method - assert_nothing_raised do - assert_emails 1 do - assert_deprecated do - TestMailer.deliver_send - end - end - end - end -end -class RespondToTest < Test::Unit::TestCase - class RespondToMailer < ActionMailer::Base; end - - def setup - set_delivery_method :test - end - - def teardown - restore_delivery_method - end - - def test_should_respond_to_new - assert_respond_to RespondToMailer, :new - end - - def test_should_respond_to_create_with_template_suffix - assert_respond_to RespondToMailer, :create_any_old_template - end - - def test_should_respond_to_deliver_with_template_suffix - assert_respond_to RespondToMailer, :deliver_any_old_template - end - - def test_should_not_respond_to_new_with_template_suffix - assert !RespondToMailer.respond_to?(:new_any_old_template) - end - - def test_should_not_respond_to_create_with_template_suffix_unless_it_is_separated_by_an_underscore - assert !RespondToMailer.respond_to?(:createany_old_template) - end - - def test_should_not_respond_to_deliver_with_template_suffix_unless_it_is_separated_by_an_underscore - assert !RespondToMailer.respond_to?(:deliverany_old_template) - end - - def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_uppercase_letter - assert !RespondToMailer.respond_to?(:create_Any_old_template) - end - - def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_uppercase_letter - assert !RespondToMailer.respond_to?(:deliver_Any_old_template) - end - - def test_should_not_respond_to_create_with_template_suffix_if_it_begins_with_a_digit - assert !RespondToMailer.respond_to?(:create_1_template) - end - - def test_should_not_respond_to_deliver_with_template_suffix_if_it_begins_with_a_digit - assert !RespondToMailer.respond_to?(:deliver_1_template) - end - - def test_should_not_respond_to_method_where_deliver_is_not_a_suffix - assert !RespondToMailer.respond_to?(:foo_deliver_template) - end - - def test_should_still_raise_exception_with_expected_message_when_calling_an_undefined_method - error = assert_raise NoMethodError do - RespondToMailer.not_a_method - end - - assert_match(/method.*not_a_method/, error.message) - end -end +end
\ No newline at end of file diff --git a/actionmailer/test/test_helper_test.rb b/actionmailer/test/test_helper_test.rb index 5a101e852f..dd62164176 100644 --- a/actionmailer/test/test_helper_test.rb +++ b/actionmailer/test/test_helper_test.rb @@ -2,11 +2,10 @@ require 'abstract_unit' class TestHelperMailer < ActionMailer::Base def test - recipients "test@example.com" - from "tester@example.com" - @world = "Earth" - render(:inline => "Hello, <%= @world %>") + mail :body => render(:inline => "Hello, <%= @world %>"), + :to => "test@example.com", + :from => "tester@example.com" end end diff --git a/actionmailer/test/old_base/url_test.rb b/actionmailer/test/url_test.rb index 573186dbee..9b2b38d9e8 100644 --- a/actionmailer/test/old_base/url_test.rb +++ b/actionmailer/test/url_test.rb @@ -18,13 +18,10 @@ class UrlTestMailer < ActionMailer::Base end def signed_up_with_url(recipient) - @recipients = recipient - @subject = "[Signed up] Welcome #{recipient}" - @from = "system@loudthinking.com" - @sent_on = Time.local(2004, 12, 12) - @recipient = recipient @welcome_url = url_for :host => "example.com", :controller => "welcome", :action => "greeting" + mail(:to => recipient, :subject => "[Signed up] Welcome #{recipient}", + :from => "system@loudthinking.com", :date => Time.local(2004, 12, 12)) end end @@ -47,6 +44,7 @@ class ActionMailerUrlTest < ActionMailer::TestCase set_delivery_method :test ActionMailer::Base.perform_deliveries = true ActionMailer::Base.deliveries.clear + ActiveSupport::Deprecation.silenced = false @recipient = 'test@localhost' end @@ -71,6 +69,7 @@ class ActionMailerUrlTest < ActionMailer::TestCase expected.body = "Hello there,\n\nMr. #{@recipient}. Please see our greeting at http://example.com/welcome/greeting http://www.basecamphq.com/welcome\n\n<img alt=\"Somelogo\" src=\"/images/somelogo.png\" />" expected.from = "system@loudthinking.com" expected.date = Time.local(2004, 12, 12) + expected.content_type = "text/html" created = nil assert_nothing_raised { created = UrlTestMailer.signed_up_with_url(@recipient) } diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index d7cfad7d6b..75d0632a6d 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,9 +1,15 @@ -* Symbols and strings in routes should yield the same behavior. Note this may break existing apps that were using symbols with the new routes API. [José Valim] +*Rails 3.1.0 (unreleased)* + +* No changes -* Add clear_helpers as a way to clean up all helpers added to this controller, maintaing just the helper with the same name as the controller. [José Valim] +*Rails 3.0.0 (August 29, 2010)* -*Rails 3.0.0 [release candidate 2] (August 23rd, 2010)* +* password_field renders with nil value by default making the use of passwords secure by default, if you want to render you should do for instance f.password_field(:password, :value => @user.password) [Santiago Pastorino] + +* Symbols and strings in routes should yield the same behavior. Note this may break existing apps that were using symbols with the new routes API. [José Valim] + +* Add clear_helpers as a way to clean up all helpers added to this controller, maintaing just the helper with the same name as the controller. [José Valim] * See http://github.com/rails/rails/compare/v3.0.0_RC...v3.0.0_RC2 for gory details @@ -11,9 +17,6 @@ * Add a header that tells Internet Explorer (all versions) to use the best available standards support. [Yehuda Katz] - -*Rails 3.0.0 [release candidate] (July 26th, 2010)* - * Allow stylesheet/javascript extensions to be changed through railties. [Josh Kalderimis] * link_to, button_to, and tag/tag_options now rely on html_escape instead of escape_once. [fxn] @@ -47,9 +50,6 @@ * Removed textilize, textilize_without_paragraph and markdown helpers. [Santiago Pastorino] - -*Rails 3.0.0 [beta 4] (June 8th, 2010)* - * Remove middleware laziness [José Valim] * Make session stores rely on request.cookie_jar and change set_session semantics to return the cookie value instead of a boolean. [José Valim] @@ -66,9 +66,6 @@ * Changed translate helper so that it doesn’t mark every translation as safe HTML. Only keys with a "_html" suffix and keys named "html" are considered to be safe HTML. All other translations are left untouched. [Craig Davey] - -*Rails 3.0.0 [beta 3] (April 13th, 2010)* - * New option :as added to form_for allows to change the object name. The old <% form_for :client, @post %> becomes <% form_for @post, :as => :client %> [spastorino] * Removed verify method in controllers. [JV] @@ -103,9 +100,6 @@ "HEAD" and #request_method returns "GET" in HEAD requests). This is for compatibility with Rack::Request [YK] - -*Rails 3.0.0 [beta 2] (April 1st, 2010)* - * #concat is now deprecated in favor of using <%= %> helpers [YK] * Block helpers now return Strings, so you can use <%= form_for @foo do |f| %>. @@ -134,9 +128,6 @@ # for just url_for include Rails.application.router.url_for - -*Rails 3.0.0 [beta 1] (February 4, 2010)* - * Fixed that PrototypeHelper#update_page should return html_safe [DHH] * Fixed that much of DateHelper wouldn't return html_safe? strings [DHH] diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index a0ce121ade..20f8601a8e 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -9,6 +9,9 @@ module AbstractController included do class_attribute :_helpers self._helpers = Module.new + + class_attribute :_helper_methods + self._helper_methods = Array.new end module ClassMethods @@ -43,7 +46,10 @@ module AbstractController # * <tt>method[, method]</tt> - A name or names of a method on the controller # to be made available on the view. def helper_method(*meths) - meths.flatten.each do |meth| + meths.flatten! + self._helper_methods += meths + + meths.each do |meth| _helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 def #{meth}(*args, &blk) controller.send(%(#{meth}), *args, &blk) @@ -98,7 +104,11 @@ module AbstractController # Clears up all existing helpers in this class, only keeping the helper # with the same name as this class. def clear_helpers + inherited_helper_methods = _helper_methods self._helpers = Module.new + self._helper_methods = Array.new + + inherited_helper_methods.each { |meth| helper_method meth } default_helper_module! unless anonymous? end diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index ca0e5d6ff6..e02578eafd 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -34,7 +34,6 @@ module ActionController autoload :UrlFor end - autoload :Dispatcher, 'action_controller/deprecated/dispatcher' autoload :Integration, 'action_controller/deprecated/integration_test' autoload :IntegrationTest, 'action_controller/deprecated/integration_test' autoload :PerformanceTest, 'action_controller/deprecated/performance_test' diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index d8d3a2335a..7a1464c2aa 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -228,6 +228,4 @@ module ActionController ActiveSupport.run_load_hooks(:action_controller, self) end -end - -require "action_controller/deprecated/base" +end
\ No newline at end of file diff --git a/actionpack/lib/action_controller/deprecated.rb b/actionpack/lib/action_controller/deprecated.rb index 9f2de57033..aa0cfc9395 100644 --- a/actionpack/lib/action_controller/deprecated.rb +++ b/actionpack/lib/action_controller/deprecated.rb @@ -1,3 +1,3 @@ ActionController::AbstractRequest = ActionController::Request = ActionDispatch::Request ActionController::AbstractResponse = ActionController::Response = ActionDispatch::Response -ActionController::Routing = ActionDispatch::Routing +ActionController::Routing = ActionDispatch::Routing
\ No newline at end of file diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb deleted file mode 100644 index 3975afcaf0..0000000000 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ /dev/null @@ -1,133 +0,0 @@ -module ActionController - class Base - # Deprecated methods. Wrap them in a module so they can be overwritten by plugins - # (like the verify method.) - module DeprecatedBehavior #:nodoc: - def relative_url_root - ActiveSupport::Deprecation.warn "ActionController::Base.relative_url_root is ineffective. " << - "Please stop using it.", caller - end - - def relative_url_root= - ActiveSupport::Deprecation.warn "ActionController::Base.relative_url_root= is ineffective. " << - "Please stop using it.", caller - end - - def consider_all_requests_local - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << - "use Rails.application.config.consider_all_requests_local instead", caller - Rails.application.config.consider_all_requests_local - end - - def consider_all_requests_local=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << - "Please configure it on your application with config.consider_all_requests_local=", caller - Rails.application.config.consider_all_requests_local = value - end - - def allow_concurrency - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << - "use Rails.application.config.allow_concurrency instead", caller - Rails.application.config.allow_concurrency - end - - def allow_concurrency=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << - "Please configure it on your application with config.allow_concurrency=", caller - Rails.application.config.allow_concurrency = value - end - - def ip_spoofing_check=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << - "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def ip_spoofing_check - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << - "Configuring ip_spoofing_check on the application configures a middleware.", caller - Rails.application.config.action_dispatch.ip_spoofing_check - end - - def cookie_verifier_secret=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret= is deprecated. " << - "Please configure it on your application with config.secret_token=", caller - end - - def cookie_verifier_secret - ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated.", caller - end - - def trusted_proxies=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << - "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def trusted_proxies - ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << - "Configuring trusted_proxies on the application configures a middleware.", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def session(*args) - ActiveSupport::Deprecation.warn( - "Disabling sessions for a single controller has been deprecated. " + - "Sessions are now lazy loaded. So if you don't access them, " + - "consider them off. You can still modify the session cookie " + - "options with request.session_options.", caller) - end - - def session=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << - "Please configure it on your application with config.session_store :cookie_store, :key => '....'", caller - if value.delete(:disabled) - Rails.application.config.session_store :disabled - else - store = Rails.application.config.session_store - Rails.application.config.session_store store, value - end - end - - # Controls the resource action separator - def resource_action_separator - @resource_action_separator ||= "/" - end - - def resource_action_separator=(val) - ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ - "works with the deprecated router DSL." - @resource_action_separator = val - end - - def use_accept_header - ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ - "The accept header is always taken into account." - end - - def use_accept_header=(val) - use_accept_header - end - - # This method has been moved to ActionDispatch::Request.filter_parameters - def filter_parameter_logging(*args, &block) - ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller) - filter = Rails.application.config.filter_parameters - filter.concat(args) - filter << block if block - filter - end - - # This was moved to a plugin - def verify(*args) - ActiveSupport::Deprecation.warn "verify was removed from Rails and is now available as a plugin. " << - "Please install it with `rails plugin install git://github.com/rails/verification.git`.", caller - end - end - - extend DeprecatedBehavior - - delegate :consider_all_requests_local, :consider_all_requests_local=, - :allow_concurrency, :allow_concurrency=, :to => :"self.class" - end -end diff --git a/actionpack/lib/action_controller/deprecated/dispatcher.rb b/actionpack/lib/action_controller/deprecated/dispatcher.rb deleted file mode 100644 index 8c21e375dd..0000000000 --- a/actionpack/lib/action_controller/deprecated/dispatcher.rb +++ /dev/null @@ -1,28 +0,0 @@ -module ActionController - class Dispatcher - class << self - def before_dispatch(*args, &block) - ActiveSupport::Deprecation.warn "ActionController::Dispatcher.before_dispatch is deprecated. " << - "Please use ActionDispatch::Callbacks.before instead.", caller - ActionDispatch::Callbacks.before(*args, &block) - end - - def after_dispatch(*args, &block) - ActiveSupport::Deprecation.warn "ActionController::Dispatcher.after_dispatch is deprecated. " << - "Please use ActionDispatch::Callbacks.after instead.", caller - ActionDispatch::Callbacks.after(*args, &block) - end - - def to_prepare(*args, &block) - ActiveSupport::Deprecation.warn "ActionController::Dispatcher.to_prepare is deprecated. " << - "Please use config.to_prepare instead", caller - ActionDispatch::Callbacks.after(*args, &block) - end - - def new - ActiveSupport::Deprecation.warn "ActionController::Dispatcher.new is deprecated, use Rails.application instead." - Rails.application - end - end - end -end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index d49465fa0b..7a9c91f563 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -6,6 +6,16 @@ module ActionController end module ClassMethods + # TODO Remove this after the old router map is removed. + def resource_action_separator + @resource_action_separator ||= "/" + end + + # TODO Remove this after the old router map is removed. + def resource_action_separator=(val) + ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated" + @resource_action_separator = val + end end # Temporary hax @@ -39,12 +49,6 @@ module ActionController def assign_shortcuts(*) end def _normalize_options(options) - if options[:action] && options[:action].to_s.include?(?/) - ActiveSupport::Deprecation.warn "Giving a path to render :action is deprecated. " << - "Please use render :template instead", caller - options[:template] = options.delete(:action) - end - options[:text] = nil if options.delete(:nothing) == true options[:text] = " " if options.key?(:text) && options[:text].nil? super diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb index acebde6ede..fb2118a8d7 100644 --- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb +++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb @@ -148,29 +148,29 @@ module ActionDispatch def build_named_route_call(records, inflection, options = {}) unless records.is_a?(Array) record = extract_record(records) - route = '' + route = [] else record = records.pop - route = records.inject("") do |string, parent| + route = records.map do |parent| if parent.is_a?(Symbol) || parent.is_a?(String) - string << "#{parent}_" + parent else - string << ActiveModel::Naming.plural(parent).singularize - string << "_" + ActiveModel::Naming.plural(parent).singularize end end end if record.is_a?(Symbol) || record.is_a?(String) - route << "#{record}_" + route << record else route << ActiveModel::Naming.plural(record) - route = route.singularize if inflection == :singular - route << "_" - route << "index_" if ActiveModel::Naming.uncountable?(record) && inflection == :plural + route = [route.join("_").singularize] if inflection == :singular + route << "index" if ActiveModel::Naming.uncountable?(record) && inflection == :plural end - action_prefix(options) + route + routing_type(options).to_s + route << routing_type(options) + + action_prefix(options) + route.join("_") end def extract_record(record_or_hash_or_array) diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 20a2e7c1f0..ff25c36fcd 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -6,9 +6,6 @@ require 'active_support/ordered_options' require 'action_view/log_subscriber' module ActionView #:nodoc: - class NonConcattingString < ActiveSupport::SafeBuffer - end - # = Action View Base # # Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 52e71a4c3a..0401e6a09b 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -38,7 +38,7 @@ module ActionView value = nil buffer = with_output_buffer { value = yield(*args) } if string = buffer.presence || value and string.is_a?(String) - NonConcattingString.new(string) + string end end diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 938da7aea7..ed83658140 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -624,19 +624,19 @@ module ActionView # # ==== Examples # password_field(:login, :pass, :size => 20) - # # => <input type="text" id="login_pass" name="login[pass]" size="20" value="#{@login.pass}" /> + # # => <input type="password" id="login_pass" name="login[pass]" size="20" /> # - # password_field(:account, :secret, :class => "form_input") - # # => <input type="text" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" /> + # password_field(:account, :secret, :class => "form_input", :value => @account.secret) + # # => <input type="password" id="account_secret" name="account[secret]" value="#{@account.secret}" class="form_input" /> # # password_field(:user, :password, :onchange => "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }") - # # => <input type="text" id="user_password" name="user[password]" value="#{@user.password}" onchange = "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }"/> + # # => <input type="password" id="user_password" name="user[password]" onchange = "if $('user[password]').length > 30 { alert('Your password needs to be shorter!'); }"/> # # password_field(:account, :pin, :size => 20, :class => 'form_input') - # # => <input type="text" id="account_pin" name="account[pin]" size="20" value="#{@account.pin}" class="form_input" /> + # # => <input type="password" id="account_pin" name="account[pin]" size="20" class="form_input" /> # def password_field(object_name, method, options = {}) - InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("password", options) + InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("password", { :value => nil }.merge!(options)) end # Returns a hidden input tag tailored for accessing a specified attribute (identified by +method+) on an object diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index ce609e01af..24e1e44c1d 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -14,13 +14,6 @@ module ActionView super(value.to_s) end alias :append= :<< - - def append_if_string=(value) - if value.is_a?(String) && !value.is_a?(NonConcattingString) - ActiveSupport::Deprecation.warn("<% %> style block helpers are deprecated. Please use <%= %>", caller) - self << value - end - end end class Template @@ -45,14 +38,6 @@ module ActionView end end - def add_stmt(src, code) - if code =~ BLOCK_EXPR - src << '@output_buffer.append_if_string= ' << code - else - super - end - end - def add_expr_escaped(src, code) src << '@output_buffer.append= ' << escaped_expr(code) << ';' end diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb index ef0df9d6a8..2600dae3c5 100644 --- a/actionpack/test/controller/assert_select_test.rb +++ b/actionpack/test/controller/assert_select_test.rb @@ -15,10 +15,8 @@ class AssertSelectTest < ActionController::TestCase class AssertSelectMailer < ActionMailer::Base def test(html) - recipients "test <test@test.host>" - from "test@test.host" - subject "Test e-mail" - part :content_type=>"text/html", :body=>html + mail :body => html, :content_type => "text/html", + :subject => "Test e-mail", :from => "test@test.host", :to => "test <test@test.host>" end end diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 032c22db3b..5ec59acf8d 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -100,20 +100,6 @@ class ControllerClassTests < ActiveSupport::TestCase assert_equal 'contained_empty', Submodule::ContainedEmptyController.controller_name end - def test_filter_parameter_logging - parameters = [] - config = mock(:config => mock(:filter_parameters => parameters)) - Rails.expects(:application).returns(config) - - assert_deprecated do - Class.new(ActionController::Base) do - filter_parameter_logging :password - end - end - - assert_equal [:password], parameters - end - def test_record_identifier assert_respond_to RecordIdentifierController.new, :dom_id assert_respond_to RecordIdentifierController.new, :dom_class diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb deleted file mode 100644 index ebe089aaf4..0000000000 --- a/actionpack/test/controller/dispatcher_test.rb +++ /dev/null @@ -1,59 +0,0 @@ -require 'abstract_unit' - -# Ensure deprecated dispatcher works -class DeprecatedDispatcherTest < ActiveSupport::TestCase - class DummyApp - def call(env) - [200, {}, 'response'] - end - end - - def setup - ActionDispatch::Callbacks.reset_callbacks(:prepare) - ActionDispatch::Callbacks.reset_callbacks(:call) - end - - def test_assert_deprecated_to_prepare - a = nil - - assert_deprecated do - ActionController::Dispatcher.to_prepare { a = 1 } - end - - assert_nil a - dispatch - assert_equal 1, a - end - - def test_assert_deprecated_before_dispatch - a = nil - - assert_deprecated do - ActionController::Dispatcher.before_dispatch { a = 1 } - end - - assert_nil a - dispatch - assert_equal 1, a - end - - def test_assert_deprecated_after_dispatch - a = nil - - assert_deprecated do - ActionController::Dispatcher.after_dispatch { a = 1 } - end - - assert_nil a - dispatch - assert_equal 1, a - end - - private - - def dispatch(cache_classes = true) - @dispatcher ||= ActionDispatch::Callbacks.new(DummyApp.new, !cache_classes) - @dispatcher.call({'rack.input' => StringIO.new('')}) - end - -end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index 4f8ff4140f..9093fa9e17 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -25,8 +25,27 @@ class AllHelpersController < ActionController::Base helper :all end +module ImpressiveLibrary + extend ActiveSupport::Concern + included do + helper_method :useful_function + end + + def useful_function() end +end + +ActionController::Base.send :include, ImpressiveLibrary + class JustMeController < ActionController::Base clear_helpers + + def flash + render :inline => "<h1><%= notice %></h1>" + end + + def lib + render :inline => '<%= useful_function %>' + end end class MeTooController < JustMeController @@ -104,6 +123,18 @@ class HelperTest < ActiveSupport::TestCase assert_equal [MeTooHelper, JustMeHelper], MeTooController._helpers.ancestors.reject(&:anonymous?) end + def test_base_helper_methods_after_clear_helpers + assert_nothing_raised do + call_controller(JustMeController, "flash") + end + end + + def test_lib_helper_methods_after_clear_helpers + assert_nothing_raised do + call_controller(JustMeController, "lib") + end + end + def test_all_helpers methods = AllHelpersController._helpers.instance_methods.map {|m| m.to_s} diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb index f7c42c7f22..8f81076299 100644 --- a/actionpack/test/template/capture_helper_test.rb +++ b/actionpack/test/template/capture_helper_test.rb @@ -15,7 +15,6 @@ class CaptureHelperTest < ActionView::TestCase end assert_nil @av.output_buffer assert_equal 'foobar', string - assert_kind_of ActionView::NonConcattingString, string end def test_capture_captures_the_value_returned_by_the_block_if_the_temporary_buffer_is_blank @@ -23,7 +22,6 @@ class CaptureHelperTest < ActionView::TestCase a + b end assert_equal 'foobar', string - assert_kind_of ActionView::NonConcattingString, string end def test_capture_returns_nil_if_the_returned_value_is_not_a_string diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb index d073100986..036f3a3cc9 100644 --- a/actionpack/test/template/erb/tag_helper_test.rb +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -2,59 +2,35 @@ require "abstract_unit" require "template/erb/helper" module ERBTest - module SharedTagHelpers - extend ActiveSupport::Testing::Declarative - - def maybe_deprecated - if @deprecated - assert_deprecated { yield } - else - yield - end + class TagHelperTest < BlockTestCase + def block_helper(str, rest) + "<%= #{str} do %>#{rest}<% end %>" end + extend ActiveSupport::Testing::Declarative + test "percent equals works for content_tag and does not require parenthesis on method call" do - maybe_deprecated { assert_equal "<div>Hello world</div>", render_content("content_tag :div", "Hello world") } + assert_equal "<div>Hello world</div>", render_content("content_tag :div", "Hello world") end test "percent equals works for javascript_tag" do expected_output = "<script type=\"text/javascript\">\n//<![CDATA[\nalert('Hello')\n//]]>\n</script>" - maybe_deprecated { assert_equal expected_output, render_content("javascript_tag", "alert('Hello')") } + assert_equal expected_output, render_content("javascript_tag", "alert('Hello')") end test "percent equals works for javascript_tag with options" do expected_output = "<script id=\"the_js_tag\" type=\"text/javascript\">\n//<![CDATA[\nalert('Hello')\n//]]>\n</script>" - maybe_deprecated { assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") } + assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") end test "percent equals works with form tags" do expected_output = %r{<form.*action="foo".*method="post">.*hello*</form>} - maybe_deprecated { assert_match expected_output, render_content("form_tag('foo')", "<%= 'hello' %>") } + assert_match expected_output, render_content("form_tag('foo')", "<%= 'hello' %>") end test "percent equals works with fieldset tags" do expected_output = "<fieldset><legend>foo</legend>hello</fieldset>" - maybe_deprecated { assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>") } + assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>") end end - - class TagHelperTest < BlockTestCase - def block_helper(str, rest) - "<%= #{str} do %>#{rest}<% end %>" - end - - include SharedTagHelpers - end - - class DeprecatedTagHelperTest < BlockTestCase - def block_helper(str, rest) - "<% __in_erb_template=true %><% #{str} do %>#{rest}<% end %>" - end - - def setup - @deprecated = true - end - - include SharedTagHelpers - end end
\ No newline at end of file diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index 8ba4aa1639..fd801e2a9e 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -167,7 +167,10 @@ class FormHelperTest < ActionView::TestCase '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title") ) assert_dom_equal( - '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title") + '<input id="post_title" name="post[title]" size="30" type="password" />', password_field("post", "title") + ) + assert_dom_equal( + '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title", :value => @post.title) ) assert_dom_equal( '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name") diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 60d4d9f4a7..229766612f 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -234,15 +234,6 @@ module RenderTestCases @view.render(:file => "test/hello_world.erb", :layout => "layouts/yield_with_render_inline_inside") end - - # TODO: Move to deprecated_tests.rb - def test_render_with_nested_layout_deprecated - assert_deprecated do - assert_equal %(<title>title</title>\n\n<div id="column">column</div>\n<div id="content">content</div>\n), - @view.render(:file => "test/deprecated_nested_layout.erb", :layout => "layouts/yield") - end - end - def test_render_with_nested_layout assert_equal %(<title>title</title>\n\n<div id="column">column</div>\n<div id="content">content</div>\n), @view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield") diff --git a/activemodel/CHANGELOG b/activemodel/CHANGELOG index 3ad8ac75aa..9c65778b59 100644 --- a/activemodel/CHANGELOG +++ b/activemodel/CHANGELOG @@ -1,19 +1,13 @@ -*Rails 3.0.0 [release candidate] (July 26th, 2010)* - -* Added ActiveModel::MassAssignmentSecurity [Eric Chapweske, Josh Kalderimis] - - -*Rails 3.0.0 [beta 4] (June 8th, 2010)* - -* JSON supports a custom root option: to_json(:root => 'custom') #4515 [Jatinder Singh] +*Rails 3.1.0 (unreleased)* +* No changes -*Rails 3.0.0 [beta 3] (April 13th, 2010)* -* No changes +*Rails 3.0.0 (August 29, 2010)* +* Added ActiveModel::MassAssignmentSecurity [Eric Chapweske, Josh Kalderimis] -*Rails 3.0.0 [beta 2] (April 1st, 2010)* +* JSON supports a custom root option: to_json(:root => 'custom') #4515 [Jatinder Singh] * #new_record? and #destroyed? were removed from ActiveModel::Lint. Use persisted? instead. A model is persisted if it's not a new_record? and it was @@ -27,19 +21,15 @@ * #to_key was added to ActiveModel::Lint so we can generate DOM IDs for AMo objects with composite keys [MG] - -*Rails 3.0.0 [beta 1] (February 4, 2010)* - * ActiveModel::Observer#add_observer! It has a custom hook to define after_find that should really be in a ActiveRecord::Observer subclass: - def add_observer!(klass) - klass.add_observer(self) - klass.class_eval 'def after_find() end' unless - klass.respond_to?(:after_find) - end + def add_observer!(klass) + klass.add_observer(self) + klass.class_eval 'def after_find() end' unless klass.respond_to?(:after_find) + end * Change the ActiveModel::Base.include_root_in_json default to true for Rails 3 [DHH] diff --git a/activemodel/lib/active_model.rb b/activemodel/lib/active_model.rb index 5ed21a39c2..9b8f843432 100644 --- a/activemodel/lib/active_model.rb +++ b/activemodel/lib/active_model.rb @@ -33,7 +33,6 @@ module ActiveModel autoload :BlockValidator, 'active_model/validator' autoload :Callbacks autoload :Conversion - autoload :DeprecatedErrorMethods autoload :Dirty autoload :EachValidator, 'active_model/validator' autoload :Errors diff --git a/activemodel/lib/active_model/deprecated_error_methods.rb b/activemodel/lib/active_model/deprecated_error_methods.rb deleted file mode 100644 index adc50773d9..0000000000 --- a/activemodel/lib/active_model/deprecated_error_methods.rb +++ /dev/null @@ -1,33 +0,0 @@ -module ActiveModel - module DeprecatedErrorMethods - def on(attribute) - message = "Errors#on have been deprecated, use Errors#[] instead.\n" - message << "Also note that the behaviour of Errors#[] has changed. Errors#[] now always returns an Array. An empty Array is " - message << "returned when there are no errors on the specified attribute." - ActiveSupport::Deprecation.warn(message) - - errors = self[attribute] - errors.size < 2 ? errors.first : errors - end - - def on_base - ActiveSupport::Deprecation.warn "Errors#on_base have been deprecated, use Errors#[:base] instead" - ActiveSupport::Deprecation.silence { on(:base) } - end - - def add_to_base(msg) - ActiveSupport::Deprecation.warn "Errors#add_to_base(msg) has been deprecated, use Errors#add(:base, msg) instead" - self[:base] << msg - end - - def invalid?(attribute) - ActiveSupport::Deprecation.warn "Errors#invalid?(attribute) has been deprecated, use Errors#[attribute].any? instead" - self[attribute].any? - end - - def each_full - ActiveSupport::Deprecation.warn "Errors#each_full has been deprecated, use Errors#to_a.each instead" - to_a.each { |error| yield error } - end - end -end diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 14312283d1..e9a61daab2 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -61,8 +61,6 @@ module ActiveModel # p.errors.full_messages # => ["name can not be nil"] # # etc.. class Errors < ActiveSupport::OrderedHash - include DeprecatedErrorMethods - CALLBACKS_OPTIONS = [:if, :unless, :on, :allow_nil, :allow_blank] # Pass in the instance of the object that is using the errors object. @@ -191,13 +189,6 @@ module ActiveModel # Will add an error message to each of the attributes in +attributes+ that is empty. def add_on_empty(attributes, options = {}) - if options && !options.is_a?(Hash) - options = { :message => options } - ActiveSupport::Deprecation.warn \ - "ActiveModel::Errors#add_on_empty(attributes, custom_message) has been deprecated.\n" + - "Instead of passing a custom_message pass an options Hash { :message => custom_message }." - end - [attributes].flatten.each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) is_empty = value.respond_to?(:empty?) ? value.empty? : false @@ -207,13 +198,6 @@ module ActiveModel # Will add an error message to each of the attributes in +attributes+ that is blank (using Object#blank?). def add_on_blank(attributes, options = {}) - if options && !options.is_a?(Hash) - options = { :message => options } - ActiveSupport::Deprecation.warn \ - "ActiveModel::Errors#add_on_blank(attributes, custom_message) has been deprecated.\n" + - "Instead of passing a custom_message pass an options Hash { :message => custom_message }." - end - [attributes].flatten.each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) add(attribute, :blank, options) if value.blank? @@ -281,13 +265,6 @@ module ActiveModel def generate_message(attribute, type = :invalid, options = {}) type = options.delete(:message) if options[:message].is_a?(Symbol) - if options[:default] - ActiveSupport::Deprecation.warn \ - "ActiveModel::Errors#generate_message(attributes, custom_message) has been deprecated.\n" + - "Use ActiveModel::Errors#generate_message(attributes, :message => 'your message') instead." - options[:message] = options.delete(:default) - end - defaults = @base.class.lookup_ancestors.map do |klass| [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.attributes.#{attribute}.#{type}", :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.underscore}.#{type}" ] diff --git a/activemodel/lib/active_model/translation.rb b/activemodel/lib/active_model/translation.rb index 6c1cecd9b7..dbb76244e4 100644 --- a/activemodel/lib/active_model/translation.rb +++ b/activemodel/lib/active_model/translation.rb @@ -54,11 +54,5 @@ module ActiveModel options.reverse_merge! :count => 1, :default => defaults I18n.translate(defaults.shift, options) end - - # Model.human_name is deprecated. Use Model.model_name.human instead. - def human_name(*args) - ActiveSupport::Deprecation.warn("human_name has been deprecated, please use model_name.human instead", caller[0,5]) - model_name.human(*args) - end end end diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index 1eed0b0c4d..4024002aaa 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -215,42 +215,6 @@ class ValidationsTest < ActiveModel::TestCase assert !t.invalid? end - def test_deprecated_error_messages_on - Topic.validates_presence_of :title - - t = Topic.new - assert t.invalid? - - [:title, "title"].each do |attribute| - assert_deprecated { assert_equal "can't be blank", t.errors.on(attribute) } - end - - Topic.validates_each(:title) do |record, attribute| - record.errors[attribute] << "invalid" - end - - assert t.invalid? - - [:title, "title"].each do |attribute| - assert_deprecated do - assert t.errors.on(attribute).include?("invalid") - assert t.errors.on(attribute).include?("can't be blank") - end - end - end - - def test_deprecated_errors_on_base_and_each - t = Topic.new - assert t.valid? - - assert_deprecated { t.errors.add_to_base "invalid topic" } - assert_deprecated { assert_equal "invalid topic", t.errors.on_base } - assert_deprecated { assert t.errors.invalid?(:base) } - - all_errors = t.errors.to_a - assert_deprecated { assert_equal all_errors, t.errors.each_full{|err| err} } - end - def test_validation_with_message_as_proc Topic.validates_presence_of(:title, :message => proc { "no blanks here".upcase }) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 384f95d0a0..62f1470287 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,4 +1,9 @@ -*Rails 3.0.0 [release candidate] (July 26th, 2010)* +*Rails 3.1.0 (unreleased)* + +* No changes + + +*Rails 3.0.0 (August 29, 2010)* * Changed update_attribute to not run callbacks and update the record directly in the database [Neeraj Singh] @@ -10,9 +15,6 @@ * PostgreSQL: ensure the database time zone matches Ruby's time zone #4895 [Aaron Patterson] - -*Rails 3.0.0 [beta 4] (June 8th, 2010)* - * Fixed that ActiveRecord::Base.compute_type would swallow NoMethodError #4751 [Andrew Bloomgarden, Andrew White] * Add index length support for MySQL. #1852 [Emili Parreno, Pratik Naik] @@ -37,9 +39,6 @@ * Observers can prevent records from saving by returning false, just like before_save and friends. #4087 [Mislav Marohnić] - -*Rails 3.0.0 [beta 3] (April 13th, 2010)* - * Add Relation extensions. [Pratik Naik] users = User.where(:admin => true).extending(User::AdminPowers) @@ -54,9 +53,6 @@ * Silenced "SHOW FIELDS" and "SET SQL_AUTO_IS_NULL=0" statements from the MySQL driver to improve log signal to noise ration in development [DHH] - -*Rails 3.0.0 [Beta 1] (February 4th, 2010)* - * PostgreSQLAdapter: set time_zone to UTC when Base.default_timezone == :utc so that Postgres doesn't incorrectly offset-adjust values inserted into TIMESTAMP WITH TIME ZONE columns. #3777 [Jack Christensen] * Allow relations to be used as scope. diff --git a/activerecord/activerecord.gemspec b/activerecord/activerecord.gemspec index dd9dc288cd..1387d6e288 100644 --- a/activerecord/activerecord.gemspec +++ b/activerecord/activerecord.gemspec @@ -23,6 +23,6 @@ Gem::Specification.new do |s| s.add_dependency('activesupport', version) s.add_dependency('activemodel', version) - s.add_dependency('arel', '~> 1.0.0.rc1') + s.add_dependency('arel', '~> 1.0.1') s.add_dependency('tzinfo', '~> 0.3.23') end diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb index 05b26cd0c4..e7e5f26ce0 100644 --- a/activerecord/lib/active_record/relation/spawn_methods.rb +++ b/activerecord/lib/active_record/relation/spawn_methods.rb @@ -8,7 +8,7 @@ module ActiveRecord ((Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS) - [:joins, :where]).each do |method| value = r.send(:"#{method}_values") - if value.present? + unless value.empty? if method == :includes merged_relation = merged_relation.includes(value) else diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb index 13efd2576c..ffe6fb95b8 100644 --- a/activerecord/test/cases/persistence_test.rb +++ b/activerecord/test/cases/persistence_test.rb @@ -367,7 +367,7 @@ class PersistencesTest < ActiveRecord::TestCase assert_equal 'super_title', t.title end - def test_update_attribute_for_udpated_at_on + def test_update_attribute_for_updated_at_on developer = Developer.find(1) prev_month = Time.now.prev_month diff --git a/activeresource/CHANGELOG b/activeresource/CHANGELOG index 605f751c5c..37da2a711c 100644 --- a/activeresource/CHANGELOG +++ b/activeresource/CHANGELOG @@ -1,20 +1,12 @@ -*Rails 3.0.0 [release candidate] (July 26th, 2010)* +*Rails 3.1.0 (unreleased)* -* No material changes +* No changes -*Rails 3.0.0 [beta 4] (June 8th, 2010)* +*Rails 3.0.0 (August 29, 2010)* * JSON: set Base.include_root_in_json = true to include a root value in the JSON: {"post": {"title": ...}}. Mirrors the Active Record option. [Santiago Pastorino] - -*Rails 3.0.0 [beta 3] (April 13th, 2010)* - -* No changes - - -*Rails 3.0.0 [beta 1] (February 4, 2010)* - * Add support for errors in JSON format. #1956 [Fabien Jakimowicz] * Recognizes 410 as Resource Gone. #2316 [Jordan Brough, Jatinder Singh] diff --git a/activeresource/lib/active_resource/http_mock.rb b/activeresource/lib/active_resource/http_mock.rb index 8753a21835..ddd3fb1f5d 100644 --- a/activeresource/lib/active_resource/http_mock.rb +++ b/activeresource/lib/active_resource/http_mock.rb @@ -29,7 +29,8 @@ module ActiveResource # # In order for a mock to deliver its content, the incoming request must match by the <tt>http_method</tt>, # +path+ and <tt>request_headers</tt>. If no match is found an InvalidRequestError exception - # will be raised letting you know you need to create a new mock for that request. + # will be raised showing you what request it could not find a response for and also what requests and response + # pairs have been recorded so you can create a new mock for that request. # # ==== Example # def setup @@ -97,10 +98,79 @@ module ActiveResource @@responses ||= [] end - # Accepts a block which declares a set of requests and responses for the HttpMock to respond to. See the main - # ActiveResource::HttpMock description for a more detailed explanation. - def respond_to(pairs = {}) #:yields: mock - reset! + # Accepts a block which declares a set of requests and responses for the HttpMock to respond to in + # the following format: + # + # mock.http_method(path, request_headers = {}, body = nil, status = 200, response_headers = {}) + # + # === Example + # + # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + # ActiveResource::HttpMock.respond_to do |mock| + # mock.post "/people.xml", {}, @matz, 201, "Location" => "/people/1.xml" + # mock.get "/people/1.xml", {}, @matz + # mock.put "/people/1.xml", {}, nil, 204 + # mock.delete "/people/1.xml", {}, nil, 200 + # end + # + # Alternatively, accepts a hash of <tt>{Request => Response}</tt> pairs allowing you to generate + # these the following format: + # + # ActiveResource::Request.new(method, path, body, request_headers) + # ActiveResource::Response.new(body, status, response_headers) + # + # === Example + # + # Request.new(:#{method}, path, nil, request_headers) + # + # @matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + # + # create_matz = ActiveResource::Request.new(:post, '/people.xml', @matz, {}) + # created_response = ActiveResource::Response.new("", 201, {"Location" => "/people/1.xml"}) + # get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil) + # ok_response = ActiveResource::Response.new("", 200, {}) + # + # pairs = {create_matz => created_response, get_matz => ok_response} + # + # ActiveResource::HttpMock.respond_to(pairs) + # + # Note, by default, every time you call +respond_to+, any previous request and response pairs stored + # in HttpMock will be deleted giving you a clean slate to work on. + # + # If you want to override this behaviour, pass in +false+ as the last argument to +respond_to+ + # + # === Example + # + # ActiveResource::HttpMock.respond_to do |mock| + # mock.send(:get, "/people/1", {}, "XML1") + # end + # ActiveResource::HttpMock.responses.length #=> 1 + # + # ActiveResource::HttpMock.respond_to(false) do |mock| + # mock.send(:get, "/people/2", {}, "XML2") + # end + # ActiveResource::HttpMock.responses.length #=> 2 + # + # This also works with passing in generated pairs of requests and responses, again, just pass in false + # as the last argument: + # + # === Example + # + # ActiveResource::HttpMock.respond_to do |mock| + # mock.send(:get, "/people/1", {}, "XML1") + # end + # ActiveResource::HttpMock.responses.length #=> 1 + # + # get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil) + # ok_response = ActiveResource::Response.new("", 200, {}) + # + # pairs = {get_matz => ok_response} + # + # ActiveResource::HttpMock.respond_to(pairs, false) + # ActiveResource::HttpMock.responses.length #=> 2 + def respond_to(*args) #:yields: mock + pairs = args.first || {} + reset! if args.last.class != FalseClass responses.concat pairs.to_a if block_given? yield Responder.new(responses) diff --git a/activeresource/test/cases/http_mock_test.rb b/activeresource/test/cases/http_mock_test.rb index a387cd20b1..d90d1e01b8 100644 --- a/activeresource/test/cases/http_mock_test.rb +++ b/activeresource/test/cases/http_mock_test.rb @@ -72,6 +72,74 @@ class HttpMockTest < ActiveSupport::TestCase end + test "allows you to send in pairs directly to the respond_to method" do + matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + + create_matz = ActiveResource::Request.new(:post, '/people.xml', matz, {}) + created_response = ActiveResource::Response.new("", 201, {"Location" => "/people/1.xml"}) + get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil) + ok_response = ActiveResource::Response.new(matz, 200, {}) + + pairs = {create_matz => created_response, get_matz => ok_response} + + ActiveResource::HttpMock.respond_to(pairs) + assert_equal 2, ActiveResource::HttpMock.responses.length + assert_equal "", ActiveResource::HttpMock.responses.assoc(create_matz)[1].body + assert_equal matz, ActiveResource::HttpMock.responses.assoc(get_matz)[1].body + end + + test "resets all mocked responses on each call to respond_to with a block by default" do + ActiveResource::HttpMock.respond_to do |mock| + mock.send(:get, "/people/1", {}, "XML1") + end + assert_equal 1, ActiveResource::HttpMock.responses.length + + ActiveResource::HttpMock.respond_to do |mock| + mock.send(:get, "/people/2", {}, "XML2") + end + assert_equal 1, ActiveResource::HttpMock.responses.length + end + + test "resets all mocked responses on each call to respond_to by passing pairs by default" do + ActiveResource::HttpMock.respond_to do |mock| + mock.send(:get, "/people/1", {}, "XML1") + end + assert_equal 1, ActiveResource::HttpMock.responses.length + + matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil) + ok_response = ActiveResource::Response.new(matz, 200, {}) + ActiveResource::HttpMock.respond_to({get_matz => ok_response}) + + assert_equal 1, ActiveResource::HttpMock.responses.length + end + + test "allows you to add new responses to the existing responses by calling a block" do + ActiveResource::HttpMock.respond_to do |mock| + mock.send(:get, "/people/1", {}, "XML1") + end + assert_equal 1, ActiveResource::HttpMock.responses.length + + ActiveResource::HttpMock.respond_to(false) do |mock| + mock.send(:get, "/people/2", {}, "XML2") + end + assert_equal 2, ActiveResource::HttpMock.responses.length + end + + test "allows you to add new responses to the existing responses by passing pairs" do + ActiveResource::HttpMock.respond_to do |mock| + mock.send(:get, "/people/1", {}, "XML1") + end + assert_equal 1, ActiveResource::HttpMock.responses.length + + matz = { :id => 1, :name => "Matz" }.to_xml(:root => "person") + get_matz = ActiveResource::Request.new(:get, '/people/1.xml', nil) + ok_response = ActiveResource::Response.new(matz, 200, {}) + ActiveResource::HttpMock.respond_to({get_matz => ok_response}, false) + + assert_equal 2, ActiveResource::HttpMock.responses.length + end + def request(method, path, headers = {}, body = nil) if [:put, :post].include? method @http.send(method, path, body, headers) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index c7f5d6f8b9..84cdc22e40 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,4 +1,13 @@ -*Rails 3.0.0 [release candidate] (July 26th, 2010)* +*Rails 3.1.0 (unreleased)* + +* No changes + + +*Rails 3.0.0 (August 29, 2010)* + +* Implemented String#strip_heredoc. [fxn] + +* Pluggable cache stores: setting config.cache_store = "custom_store" will require 'active_support/cache/custom_store' and look for the CustomStore constant. #5486 [Mike Perham] * Removed Object#returning, Object#tap should be used instead. [Santiago Pastorino] @@ -18,9 +27,6 @@ * Date#since, #ago, #beginning_of_day, #end_of_day, and #xmlschema honor now the user time zone if set. [Geoff Buesing] - -*Rails 3.0.0 [beta 4] (June 8th, 2010)* - * Extracted String#truncate from TextHelper#truncate [DHH] * Ruby 1.9: support UTF-8 case folding. #4595 [Norman Clarke] @@ -73,18 +79,12 @@ * JSON: encode objects that don't have a native JSON representation using to_hash, if available, instead of instance_values (the old fallback) or to_s (other encoders' default). Encode BigDecimal and Regexp encode as strings to conform with other encoders. Try to transcode non-UTF-8 strings. [Jeremy Kemper] - -*Rails 3.0.0 [beta 3] (April 13th, 2010)* - * HashWithIndifferentAccess: remove inherited symbolize_keys! since its keys are always strings. [Santiago Pastorino] * Improve transliteration quality. #4374 [Norman Clarke] * Speed up and add Ruby 1.9 support for ActiveSupport::Multibyte::Chars#tidy_bytes. #4350 [Norman Clarke] - -*Rails 3.0.0 [beta 2] (April 1st, 2010)* - * Reduced load time by deferring configuration of classes using ActiveSupport::on_load(:component_name) [YK] @@ -96,9 +96,6 @@ * JSON backend for YAJL. Preferred if available. #2666 [Brian Lopez] - -*Rails 3.0.0 [beta 1] (February 4, 2010)* - * Introduce class_attribute to declare inheritable class attributes. Writing an attribute on a subclass behaves just like overriding the superclass reader method. Unifies and replaces most usage of cattr_accessor, class_inheritable_attribute, superclass_delegating_attribute, and extlib_inheritable_attribute. [Jeremy Kemper, Yehuda Katz] * Time#- with a DateTime argument behaves the same as with a Time argument, i.e. returns the difference between self and arg as a Float #3476 [Geoff Buesing] diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 8153dd57de..df35540b55 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -58,7 +58,14 @@ module ActiveSupport case store when Symbol store_class_name = store.to_s.camelize - store_class = ActiveSupport::Cache.const_get(store_class_name) + store_class = + begin + require "active_support/cache/#{store}" + rescue LoadError + raise "Could not find cache store adapter for #{store} (#{$!})" + else + ActiveSupport::Cache.const_get(store_class_name) + end store_class.new(*parameters) when nil ActiveSupport::Cache::MemoryStore.new diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb index d8d1f9436e..8fb8c31ade 100644 --- a/activesupport/lib/active_support/core_ext/string.rb +++ b/activesupport/lib/active_support/core_ext/string.rb @@ -9,4 +9,5 @@ require 'active_support/core_ext/string/behavior' require 'active_support/core_ext/string/interpolation' require 'active_support/core_ext/string/output_safety' require 'active_support/core_ext/string/exclude' -require 'active_support/core_ext/string/encoding'
\ No newline at end of file +require 'active_support/core_ext/string/encoding' +require 'active_support/core_ext/string/strip' diff --git a/activesupport/lib/active_support/core_ext/string/strip.rb b/activesupport/lib/active_support/core_ext/string/strip.rb new file mode 100644 index 0000000000..086c610976 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/string/strip.rb @@ -0,0 +1,26 @@ +require 'active_support/core_ext/object/try' + +class String + # Strips indentation in heredocs. + # + # For example in + # + # if options[:usage] + # puts <<-USAGE.strip_heredoc + # This command does such and such. + # + # Supported options are: + # -h This message + # ... + # USAGE + # end + # + # the user would see the usage message aligned against the left margin. + # + # Technically, it looks for the least indented line in the whole string, and removes + # that amount of leading whitespace. + def strip_heredoc + indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0 + gsub(/^[ \t]{#{indent}}/, '') + end +end diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index f7e2ecd357..8be65c99f2 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -6,10 +6,42 @@ require 'inflector_test_cases' require 'active_support/core_ext/string' require 'active_support/time' require 'active_support/core_ext/kernel/reporting' +require 'active_support/core_ext/string/strip' class StringInflectionsTest < Test::Unit::TestCase include InflectorTestCases + def test_strip_heredoc_on_an_empty_string + assert_equal '', ''.strip_heredoc + end + + def test_strip_heredoc_on_a_string_with_no_lines + assert_equal 'x', 'x'.strip_heredoc + assert_equal 'x', ' x'.strip_heredoc + end + + def test_strip_heredoc_on_a_heredoc_with_no_margin + assert_equal "foo\nbar", "foo\nbar".strip_heredoc + assert_equal "foo\n bar", "foo\n bar".strip_heredoc + end + + def test_strip_heredoc_on_a_regular_indented_heredoc + assert_equal "foo\n bar\nbaz\n", <<-EOS.strip_heredoc + foo + bar + baz + EOS + end + + def test_strip_heredoc_on_a_regular_indented_heredoc_with_blank_lines + assert_equal "foo\n bar\n\nbaz\n", <<-EOS.strip_heredoc + foo + bar + + baz + EOS + end + def test_pluralize SingularToPlural.each do |singular, plural| assert_equal(plural, singular.pluralize) diff --git a/ci/ci_build.rb b/ci/ci_build.rb index 3591e45fcf..9539e47cdc 100755 --- a/ci/ci_build.rb +++ b/ci/ci_build.rb @@ -19,7 +19,7 @@ puts "[CruiseControl] Rails build" build_results = {} # Install required version of bundler. -bundler_install_cmd = "sudo gem install bundler --pre --no-ri --no-rdoc" +bundler_install_cmd = "sudo gem install bundler --no-ri --no-rdoc" puts "Running command: #{bundler_install_cmd}" build_results[:install_bundler] = system bundler_install_cmd diff --git a/rails.gemspec b/rails.gemspec index c90541b9c4..2af30163a0 100644 --- a/rails.gemspec +++ b/rails.gemspec @@ -25,5 +25,5 @@ Gem::Specification.new do |s| s.add_dependency('activeresource', version) s.add_dependency('actionmailer', version) s.add_dependency('railties', version) - s.add_dependency('bundler', '>= 1.0.0.rc.6') + s.add_dependency('bundler', '~> 1.0.0') end diff --git a/railties/CHANGELOG b/railties/CHANGELOG index df6718764e..6add449cc4 100644 --- a/railties/CHANGELOG +++ b/railties/CHANGELOG @@ -1,7 +1,11 @@ -*Rails 3.0.0 [release candidate] (July 26th, 2010)* +*Rails 3.1.0 (unreleased)* -* Application generation: --skip-testunit and --skip-activerecord become --skip-test-unit - and --skip-active-record respectively. [fxn] +* No changes + + +*Rails 3.0.0 (August 29, 2010)* + +* Application generation: --skip-testunit and --skip-activerecord become --skip-test-unit and --skip-active-record respectively. [fxn] * Added console to Rails::Railtie as a hook called just after console starts. [José Valim] @@ -15,19 +19,10 @@ * Made the rails command work even when you're in a subdirectory [Chad Fowler] - -*Rails 3.0.0 [beta 4] (June 8th, 2010)* - * Removed Rails Metal [Yehuda Katz, José Valim]. - -*Rails 3.0.0 [beta 3] (April 13th, 2010)* - * Renamed config.cookie_secret to config.secret_token and pass it as env key. [José Valim] - -*Rails 3.0.0 [beta 2] (April 1st, 2010)* - * Session store configuration has changed [Yehuda Katz, Carl Lerche] config.session_store :cookie_store, {:key => "..."} @@ -39,8 +34,6 @@ * Added config.generators.templates to provide alternative paths for the generators to look for templates [José Valim] -*Rails 3.0.0 [beta 1] (February 4, 2010)* - * Added "rake about" as a replacement for script/about [DHH] * Removed all the default commands in script/* and replaced them with script/rails and a rails command that'll act the same when run from within the app [DHH]. Example: diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index 696db30efb..dfc4d38112 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1296,6 +1296,31 @@ Active Support defines 3rd person aliases of +String#start_with?+ and +String#en NOTE: Defined in +active_support/core_ext/string/starts_ends_with.rb+. +h4. +strip_heredoc+ + +The method +strip_heredoc+ strips indentation in heredocs. + +For example in + +<ruby> +if options[:usage] + puts <<-USAGE.strip_heredoc + This command does such and such. + + Supported options are: + -h This message + ... + USAGE +end +</ruby> + +the user would see the usage message aligned against the left margin. + +Technically, it looks for the least indented line in the whole string, and removes +that amount of leading whitespace. + +NOTE: Defined in +active_support/core_ext/string/strip.rb+. + h4. Access h5. +at(position)+ diff --git a/railties/guides/source/contributing_to_rails.textile b/railties/guides/source/contributing_to_rails.textile index 91ffa8ccc3..7184759610 100644 --- a/railties/guides/source/contributing_to_rails.textile +++ b/railties/guides/source/contributing_to_rails.textile @@ -69,7 +69,7 @@ All of the Rails tests must pass with any code you submit, otherwise you have no NOTE: Ensure you install bundler v1.0 <shell> -gem install -v=1.0.0.rc.6 bundler +gem install bundler bundle install --without db </shell> diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile index 486142ea4b..07ef975f80 100644 --- a/railties/guides/source/initialization.textile +++ b/railties/guides/source/initialization.textile @@ -141,7 +141,7 @@ Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This * activesupport-3.0.0.gem * arel-0.4.0.gem * builder-2.1.2.gem -* bundler-1.0.0.rc.2.gem +* bundler-1.0.0.gem * erubis-2.6.6.gem * i18n-0.4.1.gem * mail-2.2.5.gem @@ -1374,6 +1374,7 @@ the _version_ file contains this code (comments stripped): module ActionPack #:nodoc: module VERSION #:nodoc: MAJOR = 3 + MINOR = 1 MINOR = 0 TINY = 0 diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index bbf28a8c08..7c41367a84 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -8,7 +8,6 @@ require 'active_support/core_ext/logger' require 'rails/application' require 'rails/version' -require 'rails/deprecation' require 'active_support/railtie' require 'action_dispatch/railtie' diff --git a/railties/lib/rails/deprecation.rb b/railties/lib/rails/deprecation.rb deleted file mode 100644 index 37896e0cae..0000000000 --- a/railties/lib/rails/deprecation.rb +++ /dev/null @@ -1,33 +0,0 @@ -require "active_support/string_inquirer" -require "active_support/basic_object" - -module Rails - class DeprecatedConstant < ActiveSupport::BasicObject - def self.deprecate(old, new) - constant = self.new(old, new) - eval "::#{old} = constant" - end - - def initialize(old, new) - @old, @new = old, new - @target = ::Kernel.eval "proc { #{@new} }" - @warned = false - end - - def method_missing(meth, *args, &block) - ::ActiveSupport::Deprecation.warn("#{@old} is deprecated. Please use #{@new}") unless @warned - @warned = true - - target = @target.call - if target.respond_to?(meth) - target.send(meth, *args, &block) - else - super - end - end - end - - DeprecatedConstant.deprecate("RAILS_ROOT", "::Rails.root.to_s") - DeprecatedConstant.deprecate("RAILS_ENV", "::Rails.env") - DeprecatedConstant.deprecate("RAILS_DEFAULT_LOGGER", "::Rails.logger") -end diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 6eba0f77e7..cdff1743ff 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -355,6 +355,8 @@ module Rails def app_name @app_name ||= File.basename(destination_root) end + + alias_method :defined_app_name, :app_name def defined_app_const_base Rails.respond_to?(:application) && defined?(Rails::Application) && @@ -362,6 +364,7 @@ module Rails end def app_const_base + defined_app_name # ensures the correct app_name if it's already defined @app_const_base ||= defined_app_const_base || app_name.gsub(/\W/, '_').squeeze('_').camelize end diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake index 306c88c261..02e22361e0 100644 --- a/railties/lib/rails/tasks/routes.rake +++ b/railties/lib/rails/tasks/routes.rake @@ -1,35 +1,28 @@ desc 'Print out all defined routes in match order, with names. Target specific controller with CONTROLLER=x.' task :routes => :environment do Rails.application.reload_routes! - - all_routes = Rails.application.routes.routes - named_routes = Rails.application.routes.named_routes.routes + all_routes = Rails.application.routes.routes if ENV['CONTROLLER'] all_routes = all_routes.select{ |route| route.defaults[:controller] == ENV['CONTROLLER'] } end routes = all_routes.collect do |route| - # TODO: The :index method is deprecated in 1.9 in favor of :key - # but we don't have :key in 1.8.7. We can remove this check when - # stop supporting 1.8.x - key = Hash.method_defined?('key') ? 'key' : 'index' - name = named_routes.send(key, route).to_s reqs = route.requirements.dup reqs[:to] = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/ reqs = reqs.empty? ? "" : reqs.inspect - {:name => name, :verb => route.verb.to_s, :path => route.path, :reqs => reqs} + {:name => route.name.to_s, :verb => route.verb.to_s, :path => route.path, :reqs => reqs} end routes.reject! { |r| r[:path] =~ %r{/rails/info/properties} } # Skip the route if it's internal info route - name_width = routes.map{ |r| r[:name] }.map(&:length).max - verb_width = routes.map{ |r| r[:verb] }.map(&:length).max - path_width = routes.map{ |r| r[:path] }.map(&:length).max + name_width = routes.map{ |r| r[:name].length }.max + verb_width = routes.map{ |r| r[:verb].length }.max + path_width = routes.map{ |r| r[:path].length }.max routes.each do |r| puts "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}" end -end
\ No newline at end of file +end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index dcd7629505..9ce2308a02 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -45,6 +45,12 @@ class AppGeneratorTest < Rails::Generators::TestCase super Rails::Generators::AppGenerator.instance_variable_set('@desc', nil) @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle') + + Kernel::silence_warnings do + Thor::Base.shell.send(:attr_accessor, :always_force) + @shell = Thor::Base.shell.new + @shell.send(:always_force=, true) + end end def teardown @@ -118,17 +124,26 @@ class AppGeneratorTest < Rails::Generators::TestCase FileUtils.mv(app_root, app_moved_root) - # forces the shell to automatically overwrite all files - Thor::Base.shell.send(:attr_accessor, :always_force) - shell = Thor::Base.shell.new - shell.send(:always_force=, true) - generator = Rails::Generators::AppGenerator.new ["rails"], { :with_dispatchers => true }, - :destination_root => app_moved_root, :shell => shell + :destination_root => app_moved_root, :shell => @shell generator.send(:app_const) silence(:stdout){ generator.send(:create_config_files) } assert_file "myapp_moved/config/environment.rb", /Myapp::Application\.initialize!/ end + + def test_rails_update_generates_correct_session_key + app_root = File.join(destination_root, 'myapp') + run_generator [app_root] + + Rails.application.config.root = app_root + Rails.application.class.stubs(:name).returns("Myapp") + Rails.application.stubs(:is_a?).returns(Rails::Application) + + generator = Rails::Generators::AppGenerator.new ["rails"], { :with_dispatchers => true }, :destination_root => app_root, :shell => @shell + generator.send(:app_const) + silence(:stdout){ generator.send(:create_config_files) } + assert_file "myapp/config/initializers/session_store.rb", /_myapp_session/ + end def test_application_names_are_not_singularized run_generator [File.join(destination_root, "hats")] |