aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile6
-rw-r--r--actionpack/CHANGELOG4
-rw-r--r--actionpack/lib/action_view/asset_paths.rb9
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb4
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb4
-rw-r--r--actionpack/lib/sprockets/assets.rake3
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb28
-rw-r--r--actionpack/test/template/sprockets_helper_test.rb44
-rw-r--r--activemodel/lib/active_model/serializers/xml.rb46
-rw-r--r--activemodel/test/cases/serializers/xml_serialization_test.rb17
-rw-r--r--activerecord/lib/active_record/serializers/xml_serializer.rb2
-rw-r--r--activerecord/test/cases/query_cache_test.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/object/to_query.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb2
-rw-r--r--activesupport/lib/active_support/message_encryptor.rb14
-rw-r--r--activesupport/lib/active_support/message_verifier.rb19
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb16
-rw-r--r--activesupport/test/core_ext/object/to_query_test.rb9
-rw-r--r--activesupport/test/message_encryptor_test.rb27
-rw-r--r--activesupport/test/message_verifier_test.rb26
-rw-r--r--railties/test/application/assets_test.rb14
23 files changed, 193 insertions, 114 deletions
diff --git a/Gemfile b/Gemfile
index 5ce420c3a3..508d083fe6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -75,7 +75,7 @@ end
platforms :jruby do
gem "ruby-debug", ">= 0.10.3"
gem "json"
- gem "activerecord-jdbcsqlite3-adapter"
+ gem "activerecord-jdbcsqlite3-adapter", ">= 1.2.0"
# This is needed by now to let tests work on JRuby
# TODO: When the JRuby guys merge jruby-openssl in
@@ -83,8 +83,8 @@ platforms :jruby do
gem "jruby-openssl"
group :db do
- gem "activerecord-jdbcmysql-adapter"
- gem "activerecord-jdbcpostgresql-adapter"
+ gem "activerecord-jdbcmysql-adapter", ">= 1.2.0"
+ gem "activerecord-jdbcpostgresql-adapter", ">= 1.2.0"
end
end
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index d01422b314..5ee14dbdf1 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -48,6 +48,10 @@
*Rails 3.1.1 (unreleased)*
+* Allow asset tag helper methods to accept :digest => false option in order to completely avoid the digest generation.
+Useful for linking assets from static html files or from emails when the user
+could probably look at an older html email with an older asset. [Santiago Pastorino]
+
* Don't mount Sprockets server at config.assets.prefix if config.assets.compile is false. [Mark J. Titorenko]
* Set relative url root in assets when controller isn't available for Sprockets (eg. Sass files using asset_path). Fixes #2435 [Guillermo Iguaran]
diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb
index 75164b8134..cf30ad7e57 100644
--- a/actionpack/lib/action_view/asset_paths.rb
+++ b/actionpack/lib/action_view/asset_paths.rb
@@ -21,14 +21,15 @@ module ActionView
# When :relative (default), the protocol will be determined by the client using current protocol
# When :request, the protocol will be the request protocol
# Otherwise, the protocol is used (E.g. :http, :https, etc)
- def compute_public_path(source, dir, ext = nil, include_host = true, protocol = nil)
+ def compute_public_path(source, dir, options = {})
source = source.to_s
return source if is_uri?(source)
- source = rewrite_extension(source, dir, ext) if ext
- source = rewrite_asset_path(source, dir)
+ options[:include_host] ||= true
+ source = rewrite_extension(source, dir, options[:ext]) if options[:ext]
+ source = rewrite_asset_path(source, dir, options)
source = rewrite_relative_url_root(source, relative_url_root)
- source = rewrite_host_and_protocol(source, protocol) if include_host
+ source = rewrite_host_and_protocol(source, options[:protocol]) if options[:include_host]
source
end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb
index 3c05173a1b..05d5f1870a 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb
@@ -60,8 +60,8 @@ module ActionView
private
- def path_to_asset(source, include_host = true, protocol = nil)
- asset_paths.compute_public_path(source, asset_name.to_s.pluralize, extension, include_host, protocol)
+ def path_to_asset(source, options = {})
+ asset_paths.compute_public_path(source, asset_name.to_s.pluralize, options.merge(:ext => extension))
end
def path_to_asset_source(source)
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
index 8b35aa8896..dd4e9ae4cc 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
@@ -41,7 +41,7 @@ module ActionView
# Break out the asset path rewrite in case plugins wish to put the asset id
# someplace other than the query string.
- def rewrite_asset_path(source, dir)
+ def rewrite_asset_path(source, dir, options = nil)
source = "/#{dir}/#{source}" unless source[0] == ?/
path = config.asset_path
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
index 25cc561608..09700bd0c5 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
@@ -83,7 +83,7 @@ module ActionView
# javascript_path "http://www.example.com/js/xmlhr" # => http://www.example.com/js/xmlhr
# javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
def javascript_path(source)
- asset_paths.compute_public_path(source, 'javascripts', 'js')
+ asset_paths.compute_public_path(source, 'javascripts', :ext => 'js')
end
alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
index 8c25d38bbd..2eb3eb31af 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
@@ -17,7 +17,7 @@ module ActionView
def asset_tag(source, options)
# We force the :request protocol here to avoid a double-download bug in IE7 and IE8
- tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => ERB::Util.html_escape(path_to_asset(source, true, :request)) }.merge(options), false, false)
+ tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => ERB::Util.html_escape(path_to_asset(source, :protocol => :request)) }.merge(options), false, false)
end
def custom_dir
@@ -61,7 +61,7 @@ module ActionView
# stylesheet_path "http://www.example.com/css/style" # => http://www.example.com/css/style
# stylesheet_path "http://www.example.com/css/style.css" # => http://www.example.com/css/style.css
def stylesheet_path(source)
- asset_paths.compute_public_path(source, 'stylesheets', 'css', true, :request)
+ asset_paths.compute_public_path(source, 'stylesheets', :ext => 'css', :protocol => :request)
end
alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route
diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake
index 9b2f3a3f94..81223b7ead 100644
--- a/actionpack/lib/sprockets/assets.rake
+++ b/actionpack/lib/sprockets/assets.rake
@@ -17,9 +17,6 @@ namespace :assets do
# Always compile files
Rails.application.config.assets.compile = true
- # Always ignore asset host
- Rails.application.config.action_controller.asset_host = nil
-
config = Rails.application.config
env = Rails.application.assets
target = Pathname.new(File.join(Rails.public_path, config.assets.prefix))
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index 998f0bceb7..457ab93ae3 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -25,38 +25,40 @@ module Sprockets
options = sources.extract_options!
debug = options.key?(:debug) ? options.delete(:debug) : debug_assets?
body = options.key?(:body) ? options.delete(:body) : false
+ digest = options.key?(:digest) ? options.delete(:digest) : digest_assets?
sources.collect do |source|
if debug && asset = asset_paths.asset_for(source, 'js')
asset.to_a.map { |dep|
- super(dep.to_s, { :src => asset_path(dep, 'js', true) }.merge!(options))
+ super(dep.to_s, { :src => asset_path(dep, :ext => 'js', :body => true, :digest => digest) }.merge!(options))
}
else
- super(source.to_s, { :src => asset_path(source, 'js', body) }.merge!(options))
+ super(source.to_s, { :src => asset_path(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options))
end
end.join("\n").html_safe
end
def stylesheet_link_tag(*sources)
options = sources.extract_options!
- debug = options.key?(:debug) ? options.delete(:debug) : debug_assets?
- body = options.key?(:body) ? options.delete(:body) : false
+ debug = options.key?(:debug) ? options.delete(:debug) : debug_assets?
+ body = options.key?(:body) ? options.delete(:body) : false
+ digest = options.key?(:digest) ? options.delete(:digest) : digest_assets?
sources.collect do |source|
if debug && asset = asset_paths.asset_for(source, 'css')
asset.to_a.map { |dep|
- super(dep.to_s, { :href => asset_path(dep, 'css', true, :request) }.merge!(options))
+ super(dep.to_s, { :href => asset_path(dep, :ext => 'css', :body => true, :protocol => :request, :digest => digest) }.merge!(options))
}
else
- super(source.to_s, { :href => asset_path(source, 'css', body, :request) }.merge!(options))
+ super(source.to_s, { :href => asset_path(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options))
end
end.join("\n").html_safe
end
- def asset_path(source, default_ext = nil, body = false, protocol = nil)
+ def asset_path(source, options = {})
source = source.logical_path if source.respond_to?(:logical_path)
- path = asset_paths.compute_public_path(source, 'assets', default_ext, true, protocol)
- body ? "#{path}?body=1" : path
+ path = asset_paths.compute_public_path(source, 'assets', options.merge(:body => true))
+ options[:body] ? "#{path}?body=1" : path
end
private
@@ -100,8 +102,8 @@ module Sprockets
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)
+ def compute_public_path(source, dir, options = {})
+ super(source, asset_prefix, options)
end
# Return the filesystem path for the source
@@ -131,11 +133,11 @@ module Sprockets
end
end
- def rewrite_asset_path(source, dir)
+ def rewrite_asset_path(source, dir, options = {})
if source[0] == ?/
source
else
- source = digest_for(source)
+ source = digest_for(source) unless options[:digest] == false
source = File.join(dir, source)
source = "/#{source}" unless source =~ /^\//
source
diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb
index 105c641712..c0fb07a29b 100644
--- a/actionpack/test/template/sprockets_helper_test.rb
+++ b/actionpack/test/template/sprockets_helper_test.rb
@@ -41,6 +41,10 @@ class SprocketsHelperTest < ActionView::TestCase
test "asset_path" do
assert_match %r{/assets/logo-[0-9a-f]+.png},
asset_path("logo.png")
+ assert_match %r{/assets/logo-[0-9a-f]+.png},
+ asset_path("logo.png", :digest => true)
+ assert_match %r{/assets/logo.png},
+ asset_path("logo.png", :digest => false)
end
test "asset_path with root relative assets" do
@@ -133,25 +137,29 @@ class SprocketsHelperTest < ActionView::TestCase
test "javascript path" do
assert_match %r{/assets/application-[0-9a-f]+.js},
- asset_path(:application, "js")
+ asset_path(:application, :ext => "js")
assert_match %r{/assets/xmlhr-[0-9a-f]+.js},
- asset_path("xmlhr", "js")
+ asset_path("xmlhr", :ext => "js")
assert_match %r{/assets/dir/xmlhr-[0-9a-f]+.js},
- asset_path("dir/xmlhr.js", "js")
+ asset_path("dir/xmlhr.js", :ext => "js")
assert_equal "/dir/xmlhr.js",
- asset_path("/dir/xmlhr", "js")
+ asset_path("/dir/xmlhr", :ext => "js")
assert_equal "http://www.example.com/js/xmlhr",
- asset_path("http://www.example.com/js/xmlhr", "js")
+ asset_path("http://www.example.com/js/xmlhr", :ext => "js")
assert_equal "http://www.example.com/js/xmlhr.js",
- asset_path("http://www.example.com/js/xmlhr.js", "js")
+ asset_path("http://www.example.com/js/xmlhr.js", :ext => "js")
end
test "javascript include tag" do
assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag(:application)
+ assert_match %r{<script src="/assets/application-[0-9a-f]+.js" type="text/javascript"></script>},
+ javascript_include_tag(:application, :digest => true)
+ assert_match %r{<script src="/assets/application.js" type="text/javascript"></script>},
+ javascript_include_tag(:application, :digest => false)
assert_match %r{<script src="/assets/xmlhr-[0-9a-f]+.js" type="text/javascript"></script>},
javascript_include_tag("xmlhr")
@@ -173,21 +181,25 @@ class SprocketsHelperTest < ActionView::TestCase
end
test "stylesheet path" do
- assert_match %r{/assets/application-[0-9a-f]+.css}, asset_path(:application, "css")
+ assert_match %r{/assets/application-[0-9a-f]+.css}, asset_path(:application, :ext => "css")
- assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", "css")
- assert_match %r{/assets/dir/style-[0-9a-f]+.css}, asset_path("dir/style.css", "css")
- assert_equal "/dir/style.css", asset_path("/dir/style.css", "css")
+ assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", :ext => "css")
+ assert_match %r{/assets/dir/style-[0-9a-f]+.css}, asset_path("dir/style.css", :ext => "css")
+ assert_equal "/dir/style.css", asset_path("/dir/style.css", :ext => "css")
assert_equal "http://www.example.com/css/style",
- asset_path("http://www.example.com/css/style", "css")
+ asset_path("http://www.example.com/css/style", :ext => "css")
assert_equal "http://www.example.com/css/style.css",
- asset_path("http://www.example.com/css/style.css", "css")
+ asset_path("http://www.example.com/css/style.css", :ext => "css")
end
test "stylesheet link tag" do
assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag(:application)
+ assert_match %r{<link href="/assets/application-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
+ stylesheet_link_tag(:application, :digest => true)
+ assert_match %r{<link href="/assets/application.css" media="screen" rel="stylesheet" type="text/css" />},
+ stylesheet_link_tag(:application, :digest => false)
assert_match %r{<link href="/assets/style-[0-9a-f]+.css" media="screen" rel="stylesheet" type="text/css" />},
stylesheet_link_tag("style")
@@ -218,14 +230,14 @@ class SprocketsHelperTest < ActionView::TestCase
test "alternate asset prefix" do
stubs(:asset_prefix).returns("/themes/test")
- assert_match %r{/themes/test/style-[0-9a-f]+.css}, asset_path("style", "css")
+ assert_match %r{/themes/test/style-[0-9a-f]+.css}, asset_path("style", :ext => "css")
end
test "alternate asset environment" do
assets = Sprockets::Environment.new
assets.append_path(FIXTURES.join("sprockets/alternate/stylesheets"))
stubs(:asset_environment).returns(assets)
- assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", "css")
+ assert_match %r{/assets/style-[0-9a-f]+.css}, asset_path("style", :ext => "css")
end
test "alternate hash based on environment" do
@@ -233,10 +245,10 @@ class SprocketsHelperTest < ActionView::TestCase
assets.version = 'development'
assets.append_path(FIXTURES.join("sprockets/alternate/stylesheets"))
stubs(:asset_environment).returns(assets)
- dev_path = asset_path("style", "css")
+ dev_path = asset_path("style", :ext => "css")
assets.version = 'production'
- prod_path = asset_path("style", "css")
+ prod_path = asset_path("style", :ext => "css")
assert_not_equal prod_path, dev_path
end
diff --git a/activemodel/lib/active_model/serializers/xml.rb b/activemodel/lib/active_model/serializers/xml.rb
index 64dda3bcee..d61d9d7119 100644
--- a/activemodel/lib/active_model/serializers/xml.rb
+++ b/activemodel/lib/active_model/serializers/xml.rb
@@ -15,10 +15,10 @@ module ActiveModel
class Attribute #:nodoc:
attr_reader :name, :value, :type
- def initialize(name, serializable, raw_value=nil)
+ def initialize(name, serializable, value)
@name, @serializable = name, serializable
- raw_value = raw_value.in_time_zone if raw_value.respond_to?(:in_time_zone)
- @value = raw_value || @serializable.send(name)
+ value = value.in_time_zone if value.respond_to?(:in_time_zone)
+ @value = value
@type = compute_type
end
@@ -49,40 +49,24 @@ module ActiveModel
def initialize(serializable, options = nil)
@serializable = serializable
@options = options ? options.dup : {}
-
- @options[:only] = Array.wrap(@options[:only]).map { |n| n.to_s }
- @options[:except] = Array.wrap(@options[:except]).map { |n| n.to_s }
end
- # To replicate the behavior in ActiveRecord#attributes, <tt>:except</tt>
- # takes precedence over <tt>:only</tt>. If <tt>:only</tt> is not set
- # for a N level model but is set for the N+1 level models,
- # then because <tt>:except</tt> is set to a default value, the second
- # level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
- # <tt>:only</tt> is set, always delete <tt>:except</tt>.
- def attributes_hash
- attributes = @serializable.attributes
- if options[:only].any?
- attributes.slice(*options[:only])
- elsif options[:except].any?
- attributes.except(*options[:except])
- else
- attributes
- end
+ def serializable_hash
+ @serializable.serializable_hash(@options.except(:include))
end
- def serializable_attributes
- attributes_hash.map do |name, value|
- self.class::Attribute.new(name, @serializable, value)
+ def serializable_collection
+ methods = Array.wrap(options[:methods]).map(&:to_s)
+ serializable_hash.map do |name, value|
+ name = name.to_s
+ if methods.include?(name)
+ self.class::MethodAttribute.new(name, @serializable, value)
+ else
+ self.class::Attribute.new(name, @serializable, value)
+ end
end
end
- def serializable_methods
- Array.wrap(options[:methods]).map do |name|
- self.class::MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
- end.compact
- end
-
def serialize
require 'builder' unless defined? ::Builder
@@ -114,7 +98,7 @@ module ActiveModel
end
def add_attributes_and_methods
- (serializable_attributes + serializable_methods).each do |attribute|
+ serializable_collection.each do |attribute|
key = ActiveSupport::XmlMini.rename_key(attribute.name, options)
ActiveSupport::XmlMini.to_tag(key, attribute.value,
options.merge(attribute.decorations))
diff --git a/activemodel/test/cases/serializers/xml_serialization_test.rb b/activemodel/test/cases/serializers/xml_serialization_test.rb
index a38ef8e223..fc73d9dcd8 100644
--- a/activemodel/test/cases/serializers/xml_serialization_test.rb
+++ b/activemodel/test/cases/serializers/xml_serialization_test.rb
@@ -33,6 +33,12 @@ class Address
end
end
+class SerializableContact < Contact
+ def serializable_hash(options={})
+ super(options.merge(:only => [:name, :age]))
+ end
+end
+
class XmlSerializationTest < ActiveModel::TestCase
def setup
@contact = Contact.new
@@ -96,6 +102,17 @@ class XmlSerializationTest < ActiveModel::TestCase
assert_match %r{<createdAt}, @xml
end
+ test "should use serialiable hash" do
+ @contact = SerializableContact.new
+ @contact.name = 'aaron stack'
+ @contact.age = 25
+
+ @xml = @contact.to_xml
+ assert_match %r{<name>aaron stack</name>}, @xml
+ assert_match %r{<age type="integer">25</age>}, @xml
+ assert_no_match %r{<awesome>}, @xml
+ end
+
test "should allow skipped types" do
@xml = @contact.to_xml :skip_types => true
assert_match %r{<age>25</age>}, @xml
diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb
index cbfa1ad609..0e7f57aa43 100644
--- a/activerecord/lib/active_record/serializers/xml_serializer.rb
+++ b/activerecord/lib/active_record/serializers/xml_serializer.rb
@@ -179,7 +179,7 @@ module ActiveRecord #:nodoc:
class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
def initialize(*args)
super
- options[:except] |= Array.wrap(@serializable.class.inheritance_column)
+ options[:except] = Array.wrap(options[:except]) | Array.wrap(@serializable.class.inheritance_column)
end
class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index e3ad0cad90..7feac2b920 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -147,13 +147,16 @@ class QueryCacheTest < ActiveRecord::TestCase
end
def test_cache_does_not_wrap_string_results_in_arrays
- require 'sqlite3/version' if current_adapter?(:SQLite3Adapter)
+ if current_adapter?(:SQLite3Adapter)
+ require 'sqlite3/version'
+ sqlite3_version = RUBY_PLATFORM =~ /java/ ? Jdbc::SQLite3::VERSION : SQLite3::VERSION
+ end
Task.cache do
# Oracle adapter returns count() as Fixnum or Float
if current_adapter?(:OracleAdapter)
assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
- elsif current_adapter?(:SQLite3Adapter) && SQLite3::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
+ elsif current_adapter?(:SQLite3Adapter) && sqlite3_version > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
# Future versions of the sqlite3 adapter will return numeric
assert_instance_of Fixnum,
Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
diff --git a/activesupport/lib/active_support/core_ext/object/to_query.rb b/activesupport/lib/active_support/core_ext/object/to_query.rb
index 3f1540f685..5d5fcf00e0 100644
--- a/activesupport/lib/active_support/core_ext/object/to_query.rb
+++ b/activesupport/lib/active_support/core_ext/object/to_query.rb
@@ -7,7 +7,7 @@ class Object
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
def to_query(key)
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
- "#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
+ "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
end
end
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index 05b39b89bf..3ae3d64fa4 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -142,7 +142,7 @@ module ActiveSupport #:nodoc:
end
UNSAFE_STRING_METHODS.each do |unsafe_method|
- class_eval <<-EOT, __FILE__, __LINE__
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
to_str.#{unsafe_method}(*args, &block) # to_str.gsub(*args, &block)
end # end
diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb
index 4f7cd12d48..e14386a85d 100644
--- a/activesupport/lib/active_support/message_encryptor.rb
+++ b/activesupport/lib/active_support/message_encryptor.rb
@@ -13,9 +13,15 @@ module ActiveSupport
class InvalidMessage < StandardError; end
OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
- def initialize(secret, cipher = 'aes-256-cbc')
+ def initialize(secret, options = {})
+ unless options.is_a?(Hash)
+ ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :cipher => 'algorithm' to specify the cipher algorithm."
+ options = { :cipher => options }
+ end
+
@secret = secret
- @cipher = cipher
+ @cipher = options[:cipher] || 'aes-256-cbc'
+ @serializer = options[:serializer] || Marshal
end
def encrypt(value)
@@ -27,7 +33,7 @@ module ActiveSupport
cipher.key = @secret
cipher.iv = iv
- encrypted_data = cipher.update(Marshal.dump(value))
+ encrypted_data = cipher.update(@serializer.dump(value))
encrypted_data << cipher.final
[encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--")
@@ -44,7 +50,7 @@ module ActiveSupport
decrypted_data = cipher.update(encrypted_data)
decrypted_data << cipher.final
- Marshal.load(decrypted_data)
+ @serializer.load(decrypted_data)
rescue OpenSSLCipherError, TypeError
raise InvalidMessage
end
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb
index 8f3946325a..9d7c81142a 100644
--- a/activesupport/lib/active_support/message_verifier.rb
+++ b/activesupport/lib/active_support/message_verifier.rb
@@ -18,12 +18,23 @@ module ActiveSupport
# self.current_user = User.find(id)
# end
#
+ # By default it uses Marshal to serialize the message. If you want to use another
+ # serialization method, you can set the serializer attribute to something that responds
+ # to dump and load, e.g.:
+ #
+ # @verifier.serializer = YAML
class MessageVerifier
class InvalidSignature < StandardError; end
- def initialize(secret, digest = 'SHA1')
+ def initialize(secret, options = {})
+ unless options.is_a?(Hash)
+ ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to specify the digest algorithm."
+ options = { :digest => options }
+ end
+
@secret = secret
- @digest = digest
+ @digest = options[:digest] || 'SHA1'
+ @serializer = options[:serializer] || Marshal
end
def verify(signed_message)
@@ -31,14 +42,14 @@ module ActiveSupport
data, digest = signed_message.split("--")
if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
- Marshal.load(ActiveSupport::Base64.decode64(data))
+ @serializer.load(ActiveSupport::Base64.decode64(data))
else
raise InvalidSignature
end
end
def generate(value)
- data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
+ data = ActiveSupport::Base64.encode64s(@serializer.dump(value))
"#{data}--#{generate_digest(data)}"
end
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index 1813ba2a4d..fa800eada2 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -9,7 +9,7 @@ require 'active_support/inflections'
class HashExtTest < Test::Unit::TestCase
class IndifferentHash < HashWithIndifferentAccess
end
-
+
class SubclassingArray < Array
end
@@ -272,14 +272,14 @@ class HashExtTest < Test::Unit::TestCase
hash = { "urls" => { "url" => [ { "address" => "1" }, { "address" => "2" } ] }}.with_indifferent_access
assert_equal "1", hash[:urls][:url].first[:address]
end
-
+
def test_should_preserve_array_subclass_when_value_is_array
array = SubclassingArray.new
array << { "address" => "1" }
hash = { "urls" => { "url" => array }}.with_indifferent_access
assert_equal SubclassingArray, hash[:urls][:url].class
end
-
+
def test_should_preserve_array_class_when_hash_value_is_frozen_array
array = SubclassingArray.new
array << { "address" => "1" }
@@ -543,7 +543,7 @@ class HashExtToParamTests < Test::Unit::TestCase
end
def test_to_param_hash
- assert_equal 'custom2=param2-1&custom=param-1', {ToParam.new('custom') => ToParam.new('param'), ToParam.new('custom2') => ToParam.new('param2')}.to_param
+ assert_equal 'custom-1=param-1&custom2-1=param2-1', {ToParam.new('custom') => ToParam.new('param'), ToParam.new('custom2') => ToParam.new('param2')}.to_param
end
def test_to_param_hash_escapes_its_keys_and_values
@@ -955,13 +955,13 @@ class HashToXmlTest < Test::Unit::TestCase
hash = Hash.from_xml(xml)
assert_equal "bacon is the best", hash['blog']['name']
end
-
+
def test_empty_cdata_from_xml
xml = "<data><![CDATA[]]></data>"
-
+
assert_equal "", Hash.from_xml(xml)["data"]
end
-
+
def test_xsd_like_types_from_xml
bacon_xml = <<-EOT
<bacon>
@@ -1004,7 +1004,7 @@ class HashToXmlTest < Test::Unit::TestCase
assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]
end
-
+
def test_should_use_default_value_for_unknown_key
hash_wia = HashWithIndifferentAccess.new(3)
assert_equal 3, hash_wia[:new_key]
diff --git a/activesupport/test/core_ext/object/to_query_test.rb b/activesupport/test/core_ext/object/to_query_test.rb
index 84da52f4bf..c146f6cc9b 100644
--- a/activesupport/test/core_ext/object/to_query_test.rb
+++ b/activesupport/test/core_ext/object/to_query_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'active_support/ordered_hash'
require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/string/output_safety.rb'
class ToQueryTest < Test::Unit::TestCase
def test_simple_conversion
@@ -11,6 +12,14 @@ class ToQueryTest < Test::Unit::TestCase
assert_query_equal 'a%3Ab=c+d', 'a:b' => 'c d'
end
+ def test_html_safe_parameter_key
+ assert_query_equal 'a%3Ab=c+d', 'a:b'.html_safe => 'c d'
+ end
+
+ def test_html_safe_parameter_value
+ assert_query_equal 'a=%5B10%5D', 'a' => '[10]'.html_safe
+ end
+
def test_nil_parameter_value
empty = Object.new
def empty.to_param; nil end
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index e45d5ecd59..83a19f8106 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -8,8 +8,20 @@ rescue LoadError, NameError
else
require 'active_support/time'
+require 'active_support/json'
-class MessageEncryptorTest < Test::Unit::TestCase
+class MessageEncryptorTest < ActiveSupport::TestCase
+
+ class JSONSerializer
+ def dump(value)
+ ActiveSupport::JSON.encode(value)
+ end
+
+ def load(value)
+ ActiveSupport::JSON.decode(value)
+ end
+ end
+
def setup
@encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64))
@data = { :some => "data", :now => Time.local(2010) }
@@ -38,8 +50,19 @@ class MessageEncryptorTest < Test::Unit::TestCase
message = @encryptor.encrypt_and_sign(@data)
assert_equal @data, @encryptor.decrypt_and_verify(message)
end
+
+ def test_alternative_serialization_method
+ encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), :serializer => JSONSerializer.new)
+ message = encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) })
+ assert_equal encryptor.decrypt_and_verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" }
+ end
-
+ def test_digest_algorithm_as_second_parameter_deprecation
+ assert_deprecated(/options hash/) do
+ ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), 'aes-256-cbc')
+ end
+ end
+
private
def assert_not_decrypted(value)
assert_raise(ActiveSupport::MessageEncryptor::InvalidMessage) do
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index 4821311244..35747abe5b 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -8,8 +8,20 @@ rescue LoadError, NameError
else
require 'active_support/time'
+require 'active_support/json'
-class MessageVerifierTest < Test::Unit::TestCase
+class MessageVerifierTest < ActiveSupport::TestCase
+
+ class JSONSerializer
+ def dump(value)
+ ActiveSupport::JSON.encode(value)
+ end
+
+ def load(value)
+ ActiveSupport::JSON.decode(value)
+ end
+ end
+
def setup
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
@data = { :some => "data", :now => Time.local(2010) }
@@ -31,6 +43,18 @@ class MessageVerifierTest < Test::Unit::TestCase
assert_not_verified("#{data}--#{hash.reverse}")
assert_not_verified("purejunk")
end
+
+ def test_alternative_serialization_method
+ verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", :serializer => JSONSerializer.new)
+ message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) })
+ assert_equal verifier.verify(message), { "foo" => 123, "bar" => "2010-01-01T00:00:00Z" }
+ end
+
+ def test_digest_algorithm_as_second_parameter_deprecation
+ assert_deprecated(/options hash/) do
+ ActiveSupport::MessageVerifier.new("secret", "SHA1")
+ end
+ end
def assert_not_verified(message)
assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 959914bcea..dfd950aae3 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -270,20 +270,6 @@ module ApplicationTests
assert_match(/\/assets\/rails-([0-z]+)\.png/, File.read(file))
end
- test "precompile ignore asset_host" do
- app_file "app/assets/javascripts/application.css.erb", "<%= asset_path 'rails.png' %>"
- add_to_config "config.action_controller.asset_host = Proc.new { |source, request| 'http://www.example.com/' }"
-
- capture(:stdout) do
- Dir.chdir(app_path){ `bundle exec rake assets:precompile` }
- end
-
- file = Dir["#{app_path}/public/assets/application.css"].first
- content = File.read(file)
- assert_match(/\/assets\/rails.png/, content)
- assert_no_match(/www\.example\.com/, content)
- end
-
test "precompile should handle utf8 filenames" do
app_file "app/assets/images/レイルズ.png", "not a image really"
add_to_config "config.assets.precompile = [ /\.png$$/, /application.(css|js)$/ ]"