Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/lifo/docrails
Browse files Browse the repository at this point in the history
* 'master' of git://github.com/lifo/docrails: (259 commits)
  Fix a small typo
  ensure authors get warnings about broken links, and ensure end users don't
  in guides generator, warn about duplicate header IDs only if WARN_DUPLICATE_HEADERS
  replace edit distance implementation with one written from scratch to avoid license issues
  removes a wrong comment in the finders guide
  updates fxn picture
  thanks but release notes are mostly frozen once they are published, and provide only an overview of the new stuff
  Added extra notes to nested model forms explanation in 2.3 release notes to cover has_one relationships
  clarifies a bit more what's the issue with check boxes and arrays of parameters
  be even more ambiguous about the order of generation of hidden input for check boxes in form helper guide
  this page referred to an :href_options keyword hash, in fact the correct keyword (the one the code responds to) is :html
  update explanation of check box generation according to f400209
  Hidden field with check box goes first.
  update rack fixture to be ruby 1.9 compat
  Better error message to try to figure out why the CI build is failing
  ruby 1.9 compat: Pathname doesn't support =~
  update rack fixture to be ruby 1.9 compat
  update metal fixtures to be ruby 1.9 compat
  Fix brittle Time.now mock
  Ensure our bundled version of rack is at the front of the load path
  ...
  • Loading branch information
packagethief committed Mar 24, 2009
2 parents 4b6458b + f7bdfe8 commit 76556b0
Show file tree
Hide file tree
Showing 294 changed files with 5,593 additions and 2,482 deletions.
5 changes: 1 addition & 4 deletions actionmailer/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
*Edge*
*2.3.2 [Final] (March 15, 2009)*

* Fixed that ActionMailer should send correctly formatted Return-Path in MAIL FROM for SMTP #1842 [Matt Jones]


*2.3.0 [RC1] (February 1st, 2009)*

* Fixed RFC-2045 quoted-printable bug #1421 [squadette]

* Fixed that no body charset would be set when there are attachments present #740 [Paweł Kondzior]
Expand Down
2 changes: 1 addition & 1 deletion actionmailer/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ spec = Gem::Specification.new do |s|
s.rubyforge_project = "actionmailer"
s.homepage = "http://www.rubyonrails.org"

s.add_dependency('actionpack', '= 2.3.0' + PKG_BUILD)
s.add_dependency('actionpack', '= 2.3.2' + PKG_BUILD)

s.has_rdoc = true
s.requirements << 'none'
Expand Down
3 changes: 2 additions & 1 deletion actionmailer/lib/action_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ module Net
end

autoload :MailHelper, 'action_mailer/mail_helper'
autoload :TMail, 'action_mailer/vendor/tmail'

require 'action_mailer/vendor/tmail'
2 changes: 1 addition & 1 deletion actionmailer/lib/action_mailer/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ def create!(method_name, *parameters) #:nodoc:
)
end
unless @parts.empty?
@content_type = "multipart/alternative"
@content_type = "multipart/alternative" if @content_type !~ /^multipart/
@parts = sort_parts(@parts, @implicit_parts_order)
end
end
Expand Down
5 changes: 4 additions & 1 deletion actionmailer/lib/action_mailer/part.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ def to_mail(defaults)
part.parts << prt
end

part.set_content_type(real_content_type, nil, ctype_attrs) if real_content_type =~ /multipart/
if real_content_type =~ /multipart/
ctype_attrs.delete 'charset'
part.set_content_type(real_content_type, nil, ctype_attrs)
end
end

headers.each { |k,v| part[k] = v }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ def test_format_style
assert_equal(Text::Format::JUSTIFY, @format_o.format_style)
assert_match(/^of freedom, and that government of the people, by the people, for the$/,
@format_o.format(GETTYSBURG).split("\n")[-3])
assert_raises(ArgumentError) { @format_o.format_style = 33 }
assert_raise(ArgumentError) { @format_o.format_style = 33 }
end

def test_tag_paragraph
Expand Down
2 changes: 1 addition & 1 deletion actionmailer/lib/action_mailer/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module ActionMailer
module VERSION #:nodoc:
MAJOR = 2
MINOR = 3
TINY = 0
TINY = 2

STRING = [MAJOR, MINOR, TINY].join('.')
end
Expand Down
30 changes: 29 additions & 1 deletion actionmailer/test/mail_layout_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ def nolayout(recipient)
body render(:inline => "Hello, <%= @world %>", :layout => false, :body => { :world => "Earth" })
end

def multipart(recipient)
def multipart(recipient, type = nil)
recipients recipient
subject "You have a mail"
from "tester@example.com"

content_type(type) if type
end
end

Expand Down Expand Up @@ -64,6 +66,19 @@ def test_should_pickup_default_layout

def test_should_pickup_multipart_layout
mail = AutoLayoutMailer.create_multipart(@recipient)
assert_equal "multipart/alternative", mail.content_type
assert_equal 2, mail.parts.size

assert_equal 'text/plain', mail.parts.first.content_type
assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body

assert_equal 'text/html', mail.parts.last.content_type
assert_equal "Hello from layout text/html multipart", mail.parts.last.body
end

def test_should_pickup_multipartmixed_layout
mail = AutoLayoutMailer.create_multipart(@recipient, "multipart/mixed")
assert_equal "multipart/mixed", mail.content_type
assert_equal 2, mail.parts.size

assert_equal 'text/plain', mail.parts.first.content_type
Expand All @@ -73,6 +88,19 @@ def test_should_pickup_multipart_layout
assert_equal "Hello from layout text/html multipart", mail.parts.last.body
end

def test_should_fix_multipart_layout
mail = AutoLayoutMailer.create_multipart(@recipient, "text/plain")
assert_equal "multipart/alternative", mail.content_type
assert_equal 2, mail.parts.size

assert_equal 'text/plain', mail.parts.first.content_type
assert_equal "text/plain layout - text/plain multipart", mail.parts.first.body

assert_equal 'text/html', mail.parts.last.content_type
assert_equal "Hello from layout text/html multipart", mail.parts.last.body
end


def test_should_pickup_layout_given_to_render
mail = AutoLayoutMailer.create_spam(@recipient)
assert_equal "Spammer layout Hello, Earth", mail.body.strip
Expand Down
3 changes: 2 additions & 1 deletion actionmailer/test/mail_service_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ def test_nested_parts
assert_equal "multipart/mixed", created.content_type
assert_equal "multipart/alternative", created.parts.first.content_type
assert_equal "bar", created.parts.first.header['foo'].to_s
assert_nil created.parts.first.charset
assert_equal "text/plain", created.parts.first.parts.first.content_type
assert_equal "text/html", created.parts.first.parts[1].content_type
assert_equal "application/octet-stream", created.parts[1].content_type
Expand Down Expand Up @@ -1068,7 +1069,7 @@ def test_should_not_respond_to_method_where_deliver_is_not_a_suffix
end

def test_should_still_raise_exception_with_expected_message_when_calling_an_undefined_method
error = assert_raises NoMethodError do
error = assert_raise NoMethodError do
RespondToMailer.not_a_method
end

Expand Down
8 changes: 4 additions & 4 deletions actionmailer/test/test_helper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_mailer_class_is_correctly_inferred
end

def test_determine_default_mailer_raises_correct_error
assert_raises(ActionMailer::NonInferrableMailerError) do
assert_raise(ActionMailer::NonInferrableMailerError) do
self.class.determine_default_mailer("NotAMailerTest")
end
end
Expand Down Expand Up @@ -84,7 +84,7 @@ def test_assert_no_emails
end

def test_assert_emails_too_few_sent
error = assert_raises ActiveSupport::TestCase::Assertion do
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_emails 2 do
TestHelperMailer.deliver_test
end
Expand All @@ -94,7 +94,7 @@ def test_assert_emails_too_few_sent
end

def test_assert_emails_too_many_sent
error = assert_raises ActiveSupport::TestCase::Assertion do
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_emails 1 do
TestHelperMailer.deliver_test
TestHelperMailer.deliver_test
Expand All @@ -105,7 +105,7 @@ def test_assert_emails_too_many_sent
end

def test_assert_no_emails_failure
error = assert_raises ActiveSupport::TestCase::Assertion do
error = assert_raise ActiveSupport::TestCase::Assertion do
assert_no_emails do
TestHelperMailer.deliver_test
end
Expand Down
13 changes: 9 additions & 4 deletions actionpack/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
*Edge*
*2.3.2 [Final] (March 15, 2009)*

* Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #<Post:0x23150b8>") [DHH]

* Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable #2095 [Gregg Pollack]

* Fixed that passing a custom form builder would be forwarded to nested fields_for calls #2023 [Eloy Duran/Nate Wiger]

* Form option helpers now support disabled option tags and the use of lambdas for selecting/disabling option tags from collections #837 [Tekin]

* Added partial scoping to TranslationHelper#translate, so if you call translate(".foo") from the people/index.html.erb template, you'll actually be calling I18n.translate("people.index.foo") [DHH]

* Fix a syntax error in current_page?() that was prevent matches against URL's with multiple query parameters #1385, #1868 [chris finne/Andrew White]

* Added localized rescue template when I18n.locale is set (ex: public/404.da.html) #1835 [José Valim]


*2.3.0 [RC1] (February 1st, 2009)*

* Make the form_for and fields_for helpers support the new Active Record nested update options. #1202 [Eloy Duran]

<% form_for @person do |person_form| %>
Expand Down
3 changes: 1 addition & 2 deletions actionpack/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ spec = Gem::Specification.new do |s|
s.has_rdoc = true
s.requirements << 'none'

s.add_dependency('activesupport', '= 2.3.0' + PKG_BUILD)
s.add_dependency('rack', '>= 0.9.0')
s.add_dependency('activesupport', '= 2.3.2' + PKG_BUILD)

s.require_path = 'lib'
s.autorequire = 'action_controller'
Expand Down
7 changes: 6 additions & 1 deletion actionpack/lib/action_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@
end
end

require 'action_controller/vendor/rack-1.0/rack'
begin
gem 'rack', '~> 1.0.0'
require 'rack'
rescue Gem::LoadError
require 'action_controller/vendor/rack-1.0/rack'
end

module ActionController
# TODO: Review explicit to see if they will automatically be handled by
Expand Down
54 changes: 43 additions & 11 deletions actionpack/lib/action_controller/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MethodNotAllowed < ActionControllerError #:nodoc:
attr_reader :allowed_methods

def initialize(*allowed_methods)
super("Only #{allowed_methods.to_sentence} requests are allowed.")
super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
@allowed_methods = allowed_methods
end

Expand Down Expand Up @@ -907,13 +907,15 @@ def render(options = nil, extra_options = {}, &block) #:doc:
extra_options[:template] = options
end

options = extra_options
elsif !options.is_a?(Hash)
extra_options[:partial] = options
options = extra_options
end

layout = pick_layout(options)
response.layout = layout.path_without_format_and_extension if layout
logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger && layout
layout = layout.path_without_format_and_extension if layout

if content_type = options[:content_type]
response.content_type = content_type.to_s
Expand Down Expand Up @@ -1101,7 +1103,6 @@ def redirect_to(options = {}, response_status = {}) #:doc:
end

response.redirected_to = options
logger.info("Redirected to #{options}") if logger && logger.info?

case options
# The scheme name consist of a letter followed by any combination of
Expand All @@ -1124,6 +1125,7 @@ def redirect_to(options = {}, response_status = {}) #:doc:

def redirect_to_full_url(url, status)
raise DoubleRenderError if performed?
logger.info("Redirected to #{url}") if logger && logger.info?
response.redirect(url, interpret_status(status))
@performed_redirect = true
end
Expand All @@ -1133,6 +1135,11 @@ def redirect_to_full_url(url, status)
# request is considered stale and should be generated from scratch. Otherwise,
# it's fresh and we don't need to generate anything and a reply of "304 Not Modified" is sent.
#
# Parameters:
# * <tt>:etag</tt>
# * <tt>:last_modified</tt>
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
#
# Example:
#
# def show
Expand All @@ -1153,20 +1160,34 @@ def stale?(options)
# Sets the etag, last_modified, or both on the response and renders a
# "304 Not Modified" response if the request is already fresh.
#
# Parameters:
# * <tt>:etag</tt>
# * <tt>:last_modified</tt>
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
#
# Example:
#
# def show
# @article = Article.find(params[:id])
# fresh_when(:etag => @article, :last_modified => @article.created_at.utc)
# fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
# end
#
# This will render the show template if the request isn't sending a matching etag or
# If-Modified-Since header and just a "304 Not Modified" response if there's a match.
#
def fresh_when(options)
options.assert_valid_keys(:etag, :last_modified)
options.assert_valid_keys(:etag, :last_modified, :public)

response.etag = options[:etag] if options[:etag]
response.last_modified = options[:last_modified] if options[:last_modified]

if options[:public]
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
cache_control.delete("private")
cache_control.delete("no-cache")
cache_control << "public"
response.headers["Cache-Control"] = cache_control.join(', ')
end

if request.fresh?(response)
head :not_modified
Expand All @@ -1178,15 +1199,26 @@ def fresh_when(options)
#
# Examples:
# expires_in 20.minutes
# expires_in 3.hours, :private => false
# expires in 3.hours, 'max-stale' => 5.hours, :private => nil, :public => true
# expires_in 3.hours, :public => true
# expires in 3.hours, 'max-stale' => 5.hours, :public => true
#
# This method will overwrite an existing Cache-Control header.
# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for more possibilities.
def expires_in(seconds, options = {}) #:doc:
cache_options = { 'max-age' => seconds, 'private' => true }.symbolize_keys.merge!(options.symbolize_keys)
cache_options.delete_if { |k,v| v.nil? or v == false }
cache_control = cache_options.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }

cache_control << "max-age=#{seconds}"
cache_control.delete("no-cache")
if options[:public]
cache_control.delete("private")
cache_control << "public"
else
cache_control << "private"
end

# This allows for additional headers to be passed through like 'max-stale' => 5.hours
cache_control += options.symbolize_keys.reject{|k,v| k == :public || k == :private }.map{ |k,v| v == true ? k.to_s : "#{k.to_s}=#{v.to_s}"}

response.headers["Cache-Control"] = cache_control.join(', ')
end

Expand Down Expand Up @@ -1298,7 +1330,7 @@ def perform_action
rescue ActionView::MissingTemplate => e
# Was the implicit template missing, or was it another template?
if e.path == default_template_name
raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller
raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence(:locale => :en)}", caller
else
raise e
end
Expand Down
Loading

0 comments on commit 76556b0

Please sign in to comment.