aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG32
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/action_controller/caching/sweeping.rb2
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb9
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb2
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb2
-rw-r--r--actionpack/lib/action_controller/record_identifier.rb2
-rw-r--r--actionpack/lib/action_controller/test_case.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb5
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb5
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb18
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/selector.rb4
-rw-r--r--actionpack/lib/action_view/asset_paths.rb2
-rw-r--r--actionpack/lib/action_view/base.rb2
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb56
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb14
-rw-r--r--actionpack/lib/sprockets/assets.rake50
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb49
-rw-r--r--actionpack/lib/sprockets/railtie.rb12
-rw-r--r--actionpack/test/abstract_unit.rb6
-rw-r--r--actionpack/test/controller/assert_select_test.rb19
-rw-r--r--actionpack/test/controller/http_basic_authentication_test.rb8
-rw-r--r--actionpack/test/controller/render_test.rb2
-rw-r--r--actionpack/test/dispatch/cookies_test.rb16
-rw-r--r--actionpack/test/fixtures/test/hello,world.erb (renamed from actionpack/test/fixtures/test/hello_w*rld.erb)0
-rw-r--r--actionpack/test/template/capture_helper_test.rb36
-rw-r--r--actionpack/test/template/record_tag_helper_test.rb41
-rw-r--r--actionpack/test/template/sprockets_helper_test.rb6
-rw-r--r--actionpack/test/template/url_helper_test.rb10
31 files changed, 335 insertions, 91 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 6b654e149e..82dfc625a6 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,21 @@
*Rails 3.2.0 (unreleased)*
+* content_tag_for and div_for can now take the collection of records. It will also yield the record as the first argument if you set a receiving argument in your block [Prem Sichanugrist]
+
+ So instead of having to do this:
+
+ @items.each do |item|
+ content_tag_for(:li, item) do
+ Title: <%= item.title %>
+ end
+ end
+
+ You can now do this:
+
+ content_tag_for(:li, @items) do |item|
+ Title: <%= item.title %>
+ end
+
* send_file now guess the mime type [Esad Hajdarevic]
* Mime type entries for PDF, ZIP and other formats were added [Esad Hajdarevic]
@@ -28,7 +44,21 @@
for your test you need to do it before the cookie jar is created.
-*Rails 3.1.0 (unreleased)*
+*Rails 3.1.1 (unreleased)*
+
+* Fixed the behavior of asset pipeline when config.assets.digest and config.assets.compile are false and requested asset isn't precompiled.
+ Before the requested asset were compiled anyway ignoring that the config.assets.compile flag is false. [Guillermo Iguaran]
+
+* CookieJar is now Enumerable. Fixes #2795
+
+* Fixed AssetNotPrecompiled error raised when rake assets:precompile is compiling certain .erb files. See GH #2763 #2765 #2805 [Guillermo Iguaran]
+
+* Manifest is correctly placed in assets path when default assets prefix is changed. Fixes #2776 [Guillermo Iguaran]
+
+* Fixed stylesheet_link_tag and javascript_include_tag to respect additional options passed by the users when debug is on. [Guillermo Iguaran]
+
+
+*Rails 3.1.0 (August 30, 2011)*
* Param values are `paramified` in controller tests. [David Chelimsky]
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 59d5bbc5ed..65b364f872 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
s.add_dependency('rack', '~> 1.3.2')
s.add_dependency('rack-test', '~> 0.6.1')
s.add_dependency('rack-mount', '~> 0.8.2')
- s.add_dependency('sprockets', '~> 2.0.0.beta.15')
+ s.add_dependency('sprockets', '~> 2.0.0')
s.add_dependency('erubis', '~> 2.7.0')
s.add_development_dependency('tzinfo', '~> 0.3.29')
diff --git a/actionpack/lib/action_controller/caching/sweeping.rb b/actionpack/lib/action_controller/caching/sweeping.rb
index 938a6ae81c..49cf70ec21 100644
--- a/actionpack/lib/action_controller/caching/sweeping.rb
+++ b/actionpack/lib/action_controller/caching/sweeping.rb
@@ -88,7 +88,7 @@ module ActionController #:nodoc:
end
def method_missing(method, *arguments, &block)
- return if @controller.nil?
+ return unless @controller
@controller.__send__(method, *arguments, &block)
end
end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 2df0e9422c..bd515bba82 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -7,9 +7,12 @@ module ActionController
# by default.
#
# In addition to using the standard template helpers provided, creating custom helpers to
- # extract complicated logic or reusable functionality is strongly encouraged. By default, the controller will
- # include a helper whose name matches that of the controller, e.g., <tt>MyController</tt> will automatically
- # include <tt>MyHelper</tt>.
+ # extract complicated logic or reusable functionality is strongly encouraged. By default, each controller
+ # will include all helpers.
+ #
+ # In previous versions of \Rails the controller will include a helper whose
+ # name matches that of the controller, e.g., <tt>MyController</tt> will automatically
+ # include <tt>MyHelper</tt>. To return old behavior set +config.action_controller.include_all_helpers+ to +false+.
#
# Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
# controller which inherits from it.
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 7420a5e7e9..264806cd36 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -145,7 +145,7 @@ module ActionController
end
def encode_credentials(user_name, password)
- "Basic #{ActiveSupport::Base64.encode64("#{user_name}:#{password}")}"
+ "Basic #{ActiveSupport::Base64.encode64s("#{user_name}:#{password}")}"
end
def authentication_request(controller, realm)
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 4f311a1cf5..f2dfb3833b 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -57,7 +57,7 @@ module ActionController
# When using <tt>redirect_to :back</tt>, if there is no referrer, RedirectBackError will be raised. You may specify some fallback
# behavior for this case by rescuing RedirectBackError.
def redirect_to(options = {}, response_status = {}) #:doc:
- raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
+ raise ActionControllerError.new("Cannot redirect to nil!") unless options
raise AbstractController::DoubleRenderError if response_body
self.status = _extract_redirect_to_status(options, response_status)
diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb
index c11d676c5e..2036442cfe 100644
--- a/actionpack/lib/action_controller/record_identifier.rb
+++ b/actionpack/lib/action_controller/record_identifier.rb
@@ -67,7 +67,7 @@ module ActionController
# This can be overwritten to customize the default generated string representation if desired.
# If you need to read back a key from a dom_id in order to query for the underlying database record,
# you should write a helper like 'person_record_from_dom_id' that will extract the key either based
- # on the default implementation (which just joins all key attributes with '-') or on your own
+ # on the default implementation (which just joins all key attributes with '_') or on your own
# overwritten version of the method. By default, this implementation passes the key string through a
# method that replaces all characters that are invalid inside DOM ids, with valid ones. You need to
# make sure yourself that your dom ids are valid, in case you overwrite this method.
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 40332da321..a83fa74795 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -79,10 +79,10 @@ module ActionController
"expecting <?> but rendering with <?>",
options, rendered.keys.join(', '))
assert_block(msg) do
- if options.nil?
- @templates.blank?
- else
+ if options
rendered.any? { |t,num| t.match(options) }
+ else
+ @templates.blank?
end
end
when Hash
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 1c312f2587..8c4615c0c1 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -85,6 +85,7 @@ module ActionDispatch
class CookieOverflow < StandardError; end
class CookieJar #:nodoc:
+ include Enumerable
# This regular expression is used to split the levels of a domain.
# The top level domain can be any string without a period or
@@ -124,6 +125,10 @@ module ActionDispatch
alias :closed? :closed
def close!; @closed = true end
+ def each(&block)
+ @cookies.each(&block)
+ end
+
# Returns the value of the cookie by +name+, or +nil+ if no such cookie exists.
def [](name)
@cookies[name.to_s]
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index a70d814749..6bcf099d2c 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -59,7 +59,10 @@ module ActionDispatch
# Note that the regexp does not allow $1 to end with a ':'
$1.constantize
rescue LoadError, NameError => const_error
- raise ActionDispatch::Session::SessionRestoreError, "Session contains objects whose class definition isn't available.\nRemember to require the classes for all objects kept in the session.\n(Original exception: #{const_error.message} [#{const_error.class}])\n"
+ raise ActionDispatch::Session::SessionRestoreError,
+ "Session contains objects whose class definition isn't available.\n" +
+ "Remember to require the classes for all objects kept in the session.\n" +
+ "(Original exception: #{const_error.message} [#{const_error.class}])\n"
end
retry
else
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index a5c1501f61..4d65173f61 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -452,7 +452,9 @@ module ActionDispatch
prefix_options = options.slice(*_route.segment_keys)
# we must actually delete prefix segment keys to avoid passing them to next url_for
_route.segment_keys.each { |k| options.delete(k) }
- _routes.url_helpers.send("#{name}_path", prefix_options)
+ prefix = _routes.url_helpers.send("#{name}_path", prefix_options)
+ prefix = '' if prefix == '/'
+ prefix
end
end
end
@@ -1036,12 +1038,12 @@ module ActionDispatch
#
# This generates the following comments routes:
#
- # GET /photos/:id/comments/new
- # POST /photos/:id/comments
- # GET /photos/:id/comments/:id
- # GET /photos/:id/comments/:id/edit
- # PUT /photos/:id/comments/:id
- # DELETE /photos/:id/comments/:id
+ # GET /photos/:photo_id/comments/new
+ # POST /photos/:photo_id/comments
+ # GET /photos/:photo_id/comments/:id
+ # GET /photos/:photo_id/comments/:id/edit
+ # PUT /photos/:photo_id/comments/:id
+ # DELETE /photos/:photo_id/comments/:id
#
# === Options
# Takes same options as <tt>Base#match</tt> as well as:
@@ -1436,7 +1438,7 @@ module ActionDispatch
name_prefix = @scope[:as]
if parent_resource
- return nil if as.nil? && action.nil?
+ return nil unless as || action
collection_name = parent_resource.collection_name
member_name = parent_resource.member_name
diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
index 5fa91d1a76..b4555f4f59 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
@@ -415,9 +415,9 @@ module ActionDispatch
assert !deliveries.empty?, "No e-mail in delivery list"
for delivery in deliveries
- for part in delivery.parts
+ for part in (delivery.parts.empty? ? [delivery] : delivery.parts)
if part["Content-Type"].to_s =~ /^text\/html\W/
- root = HTML::Document.new(part.body).root
+ root = HTML::Document.new(part.body.to_s).root
assert_select root, ":root", &block
end
end
diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb
index aae8377f8a..73f4f8ee5f 100644
--- a/actionpack/lib/action_view/asset_paths.rb
+++ b/actionpack/lib/action_view/asset_paths.rb
@@ -69,7 +69,7 @@ module ActionView
host = "#{compute_protocol(protocol)}#{host}"
end
end
- host.nil? ? source : "#{host}#{source}"
+ host ? "#{host}#{source}" : source
end
def compute_protocol(protocol)
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 43d67f2032..36c49d9c91 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -116,7 +116,7 @@ module ActionView #:nodoc:
# xml.language "en-us"
# xml.ttl "40"
#
- # for item in @recent_items
+ # @recent_items.each do |item|
# xml.item do
# xml.title(item_title(item))
# xml.description(item_description(item)) if item_description(item)
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 62f95379cd..8abd85c3a3 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -134,9 +134,9 @@ module ActionView
# WARNING: content_for is ignored in caches. So you shouldn't use it
# for elements that will be fragment cached.
def content_for(name, content = nil, &block)
- content = capture(&block) if block_given?
- if content
- @view_flow.append(name, content)
+ if content || block_given?
+ content = capture(&block) if block_given?
+ @view_flow.append(name, content) if content
nil
else
@view_flow.get(name)
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 1ceb53fe9c..13b9dc8553 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -656,7 +656,7 @@ module ActionView
if token == false || !protect_against_forgery?
''
else
- token = form_authenticity_token if token.nil?
+ token ||= form_authenticity_token
tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
end
end
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index 142a25f118..b351302d01 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -17,6 +17,19 @@ module ActionView
#
# <div id="person_123" class="person foo"> Joe Bloggs </div>
#
+ # You can also pass an array of Active Record objects, which will then
+ # get iterated over and yield each record as an argument for the block.
+ # For example:
+ #
+ # <%= div_for(@people, :class => "foo") do |person| %>
+ # <%= person.name %>
+ # <% end %>
+ #
+ # produces:
+ #
+ # <div id="person_123" class="person foo"> Joe Bloggs </div>
+ # <div id="person_124" class="person foo"> Jane Bloggs </div>
+ #
def div_for(record, *args, &block)
content_tag_for(:div, record, *args, &block)
end
@@ -42,6 +55,21 @@ module ActionView
#
# <tr id="foo_person_123" class="person">...
#
+ # You can also pass an array of objects which this method will loop through
+ # and yield the current object to the supplied block, reducing the need for
+ # having to iterate through the object (using <tt>each</tt>) beforehand.
+ # For example (assuming @people is an array of Person objects):
+ #
+ # <%= content_tag_for(:tr, @people) do |person| %>
+ # <td><%= person.first_name %></td>
+ # <td><%= person.last_name %></td>
+ # <% end %>
+ #
+ # produces:
+ #
+ # <tr id="person_123" class="person">...</tr>
+ # <tr id="person_124" class="person">...</tr>
+ #
# content_tag_for also accepts a hash of options, which will be converted to
# additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
# with the default class name for your object. For example:
@@ -52,12 +80,30 @@ module ActionView
#
# <li id="person_123" class="person bar">...
#
- def content_tag_for(tag_name, record, prefix = nil, options = nil, &block)
- options, prefix = prefix, nil if prefix.is_a?(Hash)
- options ||= {}
- options.merge!({ :class => "#{dom_class(record, prefix)} #{options[:class]}".strip, :id => dom_id(record, prefix) })
- content_tag(tag_name, options, &block)
+ def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block)
+ if single_or_multiple_records.respond_to?(:to_ary)
+ single_or_multiple_records.to_ary.map do |single_record|
+ capture { content_tag_for_single_record(tag_name, single_record, prefix, options, &block) }
+ end.join("\n").html_safe
+ else
+ content_tag_for_single_record(tag_name, single_or_multiple_records, prefix, options, &block)
+ end
end
+
+ private
+
+ # Called by <tt>content_tag_for</tt> internally to render a content tag
+ # for each record.
+ def content_tag_for_single_record(tag_name, record, prefix, options, &block)
+ options, prefix = prefix, nil if prefix.is_a?(Hash)
+ options ||= {}
+ options.merge!({ :class => "#{dom_class(record, prefix)} #{options[:class]}".strip, :id => dom_id(record, prefix) })
+ if block.arity == 0
+ content_tag(tag_name, capture(&block), options)
+ else
+ content_tag(tag_name, capture(record, &block), options)
+ end
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 4dbb0135f6..acd5e46e33 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -569,6 +569,12 @@ module ActionView
#
# current_page?(:controller => 'library', :action => 'checkout')
# # => false
+ #
+ # Let's say we're in the <tt>/products</tt> action with method POST in case of invalid product.
+ #
+ # current_page?(:controller => 'product', :action => 'index')
+ # # => false
+ #
def current_page?(options)
unless request
raise "You cannot use helpers that need to determine the current " \
@@ -576,6 +582,8 @@ module ActionView
"in a #request method"
end
+ return false unless request.get?
+
url_string = url_for(options)
# We ignore any extra parameters in the request_uri if the
@@ -596,9 +604,7 @@ module ActionView
private
def convert_options_to_data_attributes(options, html_options)
- if html_options.nil?
- link_to_remote_options?(options) ? {'data-remote' => 'true'} : {}
- else
+ if html_options
html_options = html_options.stringify_keys
html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options)
@@ -611,6 +617,8 @@ module ActionView
add_method_to_attributes!(html_options, method) if method
html_options
+ else
+ link_to_remote_options?(options) ? {'data-remote' => 'true'} : {}
end
end
diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake
index 7594ee4296..a8128d9a82 100644
--- a/actionpack/lib/sprockets/assets.rake
+++ b/actionpack/lib/sprockets/assets.rake
@@ -13,35 +13,37 @@ namespace :assets do
# Ensure that action view is loaded and the appropriate sprockets hooks get executed
ActionView::Base
- # Always perform caching so that asset_path appends the timestamps to file references.
- Rails.application.config.action_controller.perform_caching = true
+ # Always compile files
+ Rails.application.config.assets.compile = true
config = Rails.application.config
env = Rails.application.assets
- target = Rails.root.join("public#{config.assets.prefix}")
-
- if env.respond_to?(:each_logical_path)
- config.assets.precompile.each do |path|
- env.each_logical_path do |logical_path|
- if path.is_a?(Regexp)
- next unless path.match(logical_path)
- else
- next unless File.fnmatch(path.to_s, logical_path)
- end
-
- if asset = env.find_asset(logical_path)
- filename = target.join(asset.digest_path)
- mkdir_p filename.dirname
- asset.write_to(filename)
- asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/
- end
+ target = Pathname.new(File.join(Rails.public_path, config.assets.prefix))
+ manifest = {}
+ manifest_path = config.assets.manifest || target
+
+ config.assets.precompile.each do |path|
+ env.each_logical_path do |logical_path|
+ if path.is_a?(Regexp)
+ next unless path.match(logical_path)
+ else
+ next unless File.fnmatch(path.to_s, logical_path)
+ end
+
+ if asset = env.find_asset(logical_path)
+ asset_path = config.assets.digest ? asset.digest_path : logical_path
+ manifest[logical_path] = asset_path
+ filename = target.join(asset_path)
+
+ mkdir_p filename.dirname
+ asset.write_to(filename)
+ asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/
end
end
- else
- # TODO: Remove this once we're depending on sprockets beta 15
- assets = config.assets.precompile.dup
- assets << {:to => target}
- env.precompile(*assets)
+ end
+
+ File.open("#{manifest_path}/manifest.yml", 'w') do |f|
+ YAML.dump(manifest, f)
end
end
end
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index 7a2bf8bef6..3987e6e17f 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -14,6 +14,9 @@ module Sprockets
paths = RailsHelper::AssetPaths.new(config, controller)
paths.asset_environment = asset_environment
paths.asset_prefix = asset_prefix
+ paths.asset_digests = asset_digests
+ paths.compile_assets = compile_assets?
+ paths.digest_assets = digest_assets?
paths
end
end
@@ -58,8 +61,9 @@ module Sprockets
private
def debug_assets?
- config = Rails.application.config.assets
- config.allow_debugging && (config.debug || params[:debug_assets])
+ compile_assets? && (Rails.application.config.assets.debug || params[:debug_assets])
+ rescue NoMethodError
+ false
end
# Override to specify an alternative prefix for asset path generation.
@@ -72,6 +76,18 @@ module Sprockets
Rails.application.config.assets.prefix
end
+ def asset_digests
+ Rails.application.config.assets.digests
+ end
+
+ def compile_assets?
+ Rails.application.config.assets.compile
+ end
+
+ def digest_assets?
+ Rails.application.config.assets.digest
+ end
+
# Override to specify an alternative asset environment for asset
# path generation. The environment should already have been mounted
# at the prefix returned by +asset_prefix+.
@@ -80,7 +96,9 @@ module Sprockets
end
class AssetPaths < ::ActionView::AssetPaths #:nodoc:
- attr_accessor :asset_environment, :asset_prefix
+ attr_accessor :asset_environment, :asset_prefix, :asset_digests, :compile_assets, :digest_assets
+
+ class AssetNotPrecompiledError < StandardError; end
def compute_public_path(source, dir, ext=nil, include_host=true, protocol=nil)
super(source, asset_prefix, ext, include_host, protocol)
@@ -99,18 +117,25 @@ module Sprockets
end
def digest_for(logical_path)
- if asset = asset_environment[logical_path]
- return asset.digest_path
+ if asset_digests && (digest = asset_digests[logical_path])
+ return digest
end
- logical_path
+ if compile_assets
+ if digest_assets && asset = asset_environment[logical_path]
+ return asset.digest_path
+ end
+ return logical_path
+ else
+ raise AssetNotPrecompiledError.new("#{logical_path} isn't precompiled")
+ end
end
def rewrite_asset_path(source, dir)
if source[0] == ?/
source
else
- source = digest_for(source) if performing_caching?
+ source = digest_for(source)
source = File.join(dir, source)
source = "/#{source}" unless source =~ /^\//
source
@@ -124,16 +149,6 @@ module Sprockets
source
end
end
-
- def performing_caching?
- # When included in Sprockets::Context, we need to ask the
- # top-level config as the controller is not available.
- if config.action_controller.present?
- config.action_controller.perform_caching
- else
- config.perform_caching
- end
- end
end
end
end
diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb
index c21bf57935..dc991636a1 100644
--- a/actionpack/lib/sprockets/railtie.rb
+++ b/actionpack/lib/sprockets/railtie.rb
@@ -26,6 +26,16 @@ module Sprockets
end
end
+ if config.assets.manifest
+ path = File.join(config.assets.manifest, "manifest.yml")
+ else
+ path = File.join(Rails.public_path, config.assets.prefix, "manifest.yml")
+ end
+
+ if File.exist?(path)
+ config.assets.digests = YAML.load_file(path)
+ end
+
ActiveSupport.on_load(:action_view) do
include ::Sprockets::Helpers::RailsHelper
@@ -61,7 +71,7 @@ module Sprockets
mount app.assets => config.assets.prefix
end
- if config.action_controller.perform_caching
+ if config.assets.digest
app.assets = app.assets.index
end
end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index aa7a01f6c9..24d071df39 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -142,11 +142,7 @@ class RoutedRackApp
end
class BasicController
- attr_accessor :request, :params
-
- def initialize
- @params = {}
- end
+ attr_accessor :request
def config
@config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config|
diff --git a/actionpack/test/controller/assert_select_test.rb b/actionpack/test/controller/assert_select_test.rb
index 878484eb57..5eef8a32d7 100644
--- a/actionpack/test/controller/assert_select_test.rb
+++ b/actionpack/test/controller/assert_select_test.rb
@@ -20,6 +20,15 @@ class AssertSelectTest < ActionController::TestCase
end
end
+ class AssertMultipartSelectMailer < ActionMailer::Base
+ def test(options)
+ mail :subject => "Test e-mail", :from => "test@test.host", :to => "test <test@test.host>" do |format|
+ format.text { render :text => options[:text] }
+ format.html { render :text => options[:html] }
+ end
+ end
+ end
+
class AssertSelectController < ActionController::Base
def response_with=(content)
@content = content
@@ -313,6 +322,16 @@ EOF
end
end
+ def test_assert_select_email_multipart
+ AssertMultipartSelectMailer.test(:html => "<div><p>foo</p><p>bar</p></div>", :text => 'foo bar').deliver
+ assert_select_email do
+ assert_select "div:root" do
+ assert_select "p:first-child", "foo"
+ assert_select "p:last-child", "bar"
+ end
+ end
+ end
+
protected
def render_html(html)
@controller.response_with = html
diff --git a/actionpack/test/controller/http_basic_authentication_test.rb b/actionpack/test/controller/http_basic_authentication_test.rb
index bd3e13e6fa..364e96d4f6 100644
--- a/actionpack/test/controller/http_basic_authentication_test.rb
+++ b/actionpack/test/controller/http_basic_authentication_test.rb
@@ -85,6 +85,14 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
end
end
+ def test_encode_credentials_has_no_newline
+ username = 'laskjdfhalksdjfhalkjdsfhalksdjfhklsdjhalksdjfhalksdjfhlakdsjfh'
+ password = 'kjfhueyt9485osdfasdkljfh4lkjhakldjfhalkdsjf'
+ result = ActionController::HttpAuthentication::Basic.encode_credentials(
+ username, password)
+ assert_no_match(/\n/, result)
+ end
+
test "authentication request without credential" do
get :display
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 6bcd606bf4..c46755417f 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -410,7 +410,7 @@ class TestController < ActionController::Base
end
def render_with_explicit_escaped_template
- render :template => "test/hello_w*rld"
+ render :template => "test/hello,world"
end
def render_with_explicit_string_template
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index fb67ecb07d..49da448001 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -148,6 +148,22 @@ class CookiesTest < ActionController::TestCase
@request.host = "www.nextangle.com"
end
+ def test_each
+ request.cookie_jar['foo'] = :bar
+ list = []
+ request.cookie_jar.each do |k,v|
+ list << [k, v]
+ end
+
+ assert_equal [['foo', :bar]], list
+ end
+
+ def test_enumerable
+ request.cookie_jar['foo'] = :bar
+ actual = request.cookie_jar.map { |k,v| [k.to_s, v.to_s] }
+ assert_equal [['foo', 'bar']], actual
+ end
+
def test_key_methods
assert !request.cookie_jar.key?(:foo)
assert !request.cookie_jar.has_key?("foo")
diff --git a/actionpack/test/fixtures/test/hello_w*rld.erb b/actionpack/test/fixtures/test/hello,world.erb
index bc8fa5e0ca..bc8fa5e0ca 100644
--- a/actionpack/test/fixtures/test/hello_w*rld.erb
+++ b/actionpack/test/fixtures/test/hello,world.erb
diff --git a/actionpack/test/template/capture_helper_test.rb b/actionpack/test/template/capture_helper_test.rb
index a9157e711c..13e2d5b595 100644
--- a/actionpack/test/template/capture_helper_test.rb
+++ b/actionpack/test/template/capture_helper_test.rb
@@ -46,6 +46,42 @@ class CaptureHelperTest < ActionView::TestCase
assert_equal "bar", content_for(:bar)
end
+ def test_content_for_with_multiple_calls
+ assert ! content_for?(:title)
+ content_for :title, 'foo'
+ content_for :title, 'bar'
+ assert_equal 'foobar', content_for(:title)
+ end
+
+ def test_content_for_with_block
+ assert ! content_for?(:title)
+ content_for :title do
+ output_buffer << 'foo'
+ output_buffer << 'bar'
+ nil
+ end
+ assert_equal 'foobar', content_for(:title)
+ end
+
+ def test_content_for_with_whitespace_block
+ assert ! content_for?(:title)
+ content_for :title, 'foo'
+ content_for :title do
+ output_buffer << " \n "
+ nil
+ end
+ content_for :title, 'bar'
+ assert_equal 'foobar', content_for(:title)
+ end
+
+ def test_content_for_returns_nil_when_writing
+ assert ! content_for?(:title)
+ assert_equal nil, content_for(:title, 'foo')
+ assert_equal nil, content_for(:title) { output_buffer << 'bar'; nil }
+ assert_equal nil, content_for(:title) { output_buffer << " \n "; nil }
+ assert_equal 'foobar', content_for(:title)
+ end
+
def test_content_for_question_mark
assert ! content_for?(:title)
content_for :title, 'title'
diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb
index 1ba14e8bc9..7f23629e05 100644
--- a/actionpack/test/template/record_tag_helper_test.rb
+++ b/actionpack/test/template/record_tag_helper_test.rb
@@ -4,11 +4,20 @@ require 'controller/fake_models'
class Post
extend ActiveModel::Naming
include ActiveModel::Conversion
+ attr_writer :id, :body
+
+ def initialize
+ @id = nil
+ @body = nil
+ super
+ end
+
def id
- 45
+ @id || 45
end
+
def body
- super || "What a wonderful world!"
+ super || @body || "What a wonderful world!"
end
end
@@ -58,4 +67,32 @@ class RecordTagHelperTest < ActionView::TestCase
actual = div_for(@post, :class => "bar") { concat @post.body }
assert_dom_equal expected, actual
end
+
+ def test_content_tag_for_collection
+ post_1 = Post.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
+ post_2 = Post.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
+ expected = %(<li class="post" id="post_101">Hello!</li>\n<li class="post" id="post_102">World!</li>)
+ actual = content_tag_for(:li, [post_1, post_2]) { |post| concat post.body }
+ assert_dom_equal expected, actual
+ end
+
+ def test_div_for_collection
+ post_1 = Post.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
+ post_2 = Post.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
+ expected = %(<div class="post" id="post_101">Hello!</div>\n<div class="post" id="post_102">World!</div>)
+ actual = div_for([post_1, post_2]) { |post| concat post.body }
+ assert_dom_equal expected, actual
+ end
+
+ def test_content_tag_for_single_record_is_html_safe
+ result = div_for(@post, :class => "bar") { concat @post.body }
+ assert result.html_safe?
+ end
+
+ def test_content_tag_for_collection_is_html_safe
+ post_1 = Post.new.tap { |post| post.id = 101; post.body = "Hello!"; post.persisted = true }
+ post_2 = Post.new.tap { |post| post.id = 102; post.body = "World!"; post.persisted = true }
+ result = content_tag_for(:li, [post_1, post_2]) { |post| concat post.body }
+ assert result.html_safe?
+ end
end
diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb
index 6c1f97a44a..ae4cb1f0aa 100644
--- a/actionpack/test/template/sprockets_helper_test.rb
+++ b/actionpack/test/template/sprockets_helper_test.rb
@@ -30,6 +30,8 @@ class SprocketsHelperTest < ActionView::TestCase
@config = config
@config.action_controller ||= ActiveSupport::InheritableOptions.new
@config.perform_caching = true
+ @config.assets.digest = true
+ @config.assets.compile = true
end
def url_for(*args)
@@ -157,7 +159,7 @@ class SprocketsHelperTest < ActionView::TestCase
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
javascript_include_tag(:application, :debug => true)
- @config.assets.allow_debugging = true
+ @config.assets.compile = true
@config.assets.debug = true
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js\?body=1" type="text/javascript"></script>\n<script src="/assets/application-[0-9a-f]+.js\?body=1" type="text/javascript"></script>},
javascript_include_tag(:application)
@@ -198,7 +200,7 @@ class SprocketsHelperTest < ActionView::TestCase
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application, :debug => true)
- @config.assets.allow_debugging = true
+ @config.assets.compile = true
@config.assets.debug = true
assert_match %r{<link href="/assets/style-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />\n<link href="/assets/application-[0-9a-f]+.css\?body=1" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index 78245c1f95..dbac2e1fc0 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -304,8 +304,8 @@ class UrlHelperTest < ActiveSupport::TestCase
assert_equal "Showing", link_to_if(false, "Showing", url_hash)
end
- def request_for_url(url)
- env = Rack::MockRequest.env_for("http://www.example.com#{url}")
+ def request_for_url(url, opts = {})
+ env = Rack::MockRequest.env_for("http://www.example.com#{url}", opts)
ActionDispatch::Request.new(env)
end
@@ -329,6 +329,12 @@ class UrlHelperTest < ActiveSupport::TestCase
assert current_page?("http://www.example.com/?order=desc&page=1")
end
+ def test_current_page_with_not_get_verb
+ @request = request_for_url("/events", :method => :post)
+
+ assert !current_page?('/events')
+ end
+
def test_link_unless_current
@request = request_for_url("/")