提交 915f108d 编写于 作者: J José Valim

Merge branch 'master' of git://github.com/rails/rails

......@@ -168,7 +168,7 @@ def send_file_headers!(options)
end
headers.merge!(
'Content-Length' => options[:length],
'Content-Length' => options[:length].to_s,
'Content-Disposition' => disposition,
'Content-Transfer-Encoding' => 'binary'
)
......
require 'cgi'
require 'action_view/helpers/url_helper'
require 'action_view/helpers/tag_helper'
require 'active_support/core_ext/file'
module ActionView
module Helpers #:nodoc:
......@@ -285,7 +286,7 @@ def javascript_include_tag(*sources)
end
javascript_src_tag(joined_javascript_name, options)
else
expand_javascript_sources(sources, recursive).collect { |source| javascript_src_tag(source, options) }.join("\n")
ensure_javascript_sources!(expand_javascript_sources(sources, recursive)).collect { |source| javascript_src_tag(source, options) }.join("\n")
end
end
......@@ -434,7 +435,7 @@ def stylesheet_link_tag(*sources)
end
stylesheet_tag(joined_stylesheet_name, options)
else
expand_stylesheet_sources(sources, recursive).collect { |source| stylesheet_tag(source, options) }.join("\n")
ensure_stylesheet_sources!(expand_stylesheet_sources(sources, recursive)).collect { |source| stylesheet_tag(source, options) }.join("\n")
end
end
......@@ -664,13 +665,28 @@ def determine_source(source, collection)
end
end
def ensure_stylesheet_sources!(sources)
sources.each do |source|
asset_file_path!(path_to_stylesheet(source))
end
return sources
end
def ensure_javascript_sources!(sources)
sources.each do |source|
asset_file_path!(path_to_javascript(source))
end
return sources
end
def join_asset_file_contents(paths)
paths.collect { |path| File.read(asset_file_path(path)) }.join("\n\n")
paths.collect { |path| File.read(asset_file_path!(path)) }.join("\n\n")
end
def write_asset_file_contents(joined_asset_path, asset_paths)
FileUtils.mkdir_p(File.dirname(joined_asset_path))
File.open(joined_asset_path, "w+") { |cache| cache.write(join_asset_file_contents(asset_paths)) }
File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
# Set mtime to the latest of the combined files to allow for
# consistent ETag without a shared filesystem.
......@@ -682,6 +698,14 @@ def asset_file_path(path)
File.join(ASSETS_DIR, path.split('?').first)
end
def asset_file_path!(path)
unless path =~ %r{^[-a-z]+://}
absolute_path = asset_file_path(path)
raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
return absolute_path
end
end
def collect_asset_files(*path)
dir = path.first
......
......@@ -232,18 +232,6 @@ def _render_partial_with_block(layout, block, options)
ensure
@_proc_for_layout = nil
end
def _deprecated_ivar_assign(template)
if respond_to?(:controller)
ivar = :"@#{template.variable_name}"
object =
if controller.instance_variable_defined?(ivar)
ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
controller.instance_variable_get(ivar),
"#{ivar} will no longer be implicitly assigned to #{template.variable_name}")
end
end
end
def _render_partial_with_layout(layout, options)
if layout
......@@ -253,18 +241,6 @@ def _render_partial_with_layout(layout, options)
content = _render_partial(options)
return _render_content_with_layout(content, layout, options[:locals])
end
def _deprecated_ivar_assign(template)
if respond_to?(:controller)
ivar = :"@#{template.variable_name}"
object =
if controller.instance_variable_defined?(ivar)
ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
controller.instance_variable_get(ivar),
"#{ivar} will no longer be implicitly assigned to #{template.variable_name}")
end
end
end
def _array_like_objects
array_like = [Array]
......@@ -290,8 +266,6 @@ def _render_partial_object(template, options, object = nil)
end
def _set_locals(object, locals, template, options)
object ||= _deprecated_ivar_assign(template)
locals[:object] = locals[template.variable_name] = object
locals[options[:as]] = object if options[:as]
end
......
require 'builder'
module ActionView
module TemplateHandlers
class Builder < TemplateHandler
......@@ -8,6 +6,7 @@ class Builder < TemplateHandler
self.default_format = Mime::XML
def compile(template)
require 'builder'
"xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
......
require 'erb'
require 'active_support/core_ext/class/attribute_accessors'
module ActionView
......@@ -16,6 +15,8 @@ class ERB < TemplateHandler
self.default_format = Mime::HTML
def compile(template)
require 'erb'
magic = $1 if template.source =~ /\A(<%#.*coding:\s*(\S+)\s*-?%>)/
erb = "#{magic}<% __in_erb_template=true %>#{template.source}"
::ERB.new(erb, nil, erb_trim_mode, '@output_buffer').src
......
......@@ -1268,13 +1268,6 @@ def test_partial_hash_collection_with_locals
assert_equal "Hola: PratikHola: Amy", @response.body
end
def test_partial_with_implicit_local_assignment
assert_deprecated do
get :partial_with_implicit_local_assignment
assert_equal "Hello: Marcel", @response.body
end
end
def test_render_missing_partial_template
assert_raise(ActionView::MissingTemplate) do
get :missing_partial
......
......@@ -115,7 +115,7 @@ def test_send_file_headers!
@controller.send(:send_file_headers!, options)
h = @controller.headers
assert_equal 1, h['Content-Length']
assert_equal '1', h['Content-Length']
assert_equal 'image/png', @controller.content_type
assert_equal 'disposition; filename="filename"', h['Content-Disposition']
assert_equal 'binary', h['Content-Transfer-Encoding']
......
absolute
\ No newline at end of file
// cools.js
\ No newline at end of file
/*file.css*/
\ No newline at end of file
// common.javascript
\ No newline at end of file
/* random.styles */
\ No newline at end of file
......@@ -75,22 +75,22 @@ def teardown
}
JavascriptIncludeToTag = {
%(javascript_include_tag("xmlhr")) => %(<script src="/javascripts/xmlhr.js" type="text/javascript"></script>),
%(javascript_include_tag("xmlhr.js")) => %(<script src="/javascripts/xmlhr.js" type="text/javascript"></script>),
%(javascript_include_tag("xmlhr", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/xmlhr.js" type="text/javascript"></script>),
%(javascript_include_tag("bank")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("bank.js")) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("bank", :lang => "vbscript")) => %(<script lang="vbscript" src="/javascripts/bank.js" type="text/javascript"></script>),
%(javascript_include_tag("common.javascript", "/elsewhere/cools")) => %(<script src="/javascripts/common.javascript" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>),
%(javascript_include_tag(:defaults)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag(:all)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
%(javascript_include_tag(:all, :recursive => true)) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/subdir/subdir.js" type="text/javascript"></script>\n<script src="/javascripts/version.1.0.js" type="text/javascript"></script>),
%(javascript_include_tag(:defaults, "test")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag("test", :defaults)) => %(<script src="/javascripts/test.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>)
%(javascript_include_tag(:defaults, "bank")) => %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>),
%(javascript_include_tag("bank", :defaults)) => %(<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>)
}
StylePathToTag = {
%(stylesheet_path("style")) => %(/stylesheets/style.css),
%(stylesheet_path("style.css")) => %(/stylesheets/style.css),
%(stylesheet_path('dir/file')) => %(/stylesheets/dir/file.css),
%(stylesheet_path('/dir/file.rcss')) => %(/dir/file.rcss)
%(stylesheet_path("bank")) => %(/stylesheets/bank.css),
%(stylesheet_path("bank.css")) => %(/stylesheets/bank.css),
%(stylesheet_path('subdir/subdir')) => %(/stylesheets/subdir/subdir.css),
%(stylesheet_path('/subdir/subdir.css')) => %(/subdir/subdir.css)
}
PathToStyleToTag = {
......@@ -101,15 +101,16 @@ def teardown
}
StyleLinkToTag = {
%(stylesheet_link_tag("style")) => %(<link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("style.css")) => %(<link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("/dir/file")) => %(<link href="/dir/file.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("dir/file")) => %(<link href="/stylesheets/dir/file.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("style", :media => "all")) => %(<link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("bank")) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("bank.css")) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("/elsewhere/file")) => %(<link href="/elsewhere/file.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("subdir/subdir")) => %(<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("bank", :media => "all")) => %(<link href="/stylesheets/bank.css" media="all" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag(:all)) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag(:all, :recursive => true)) => %(<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag(:all, :media => "all")) => %(<link href="/stylesheets/bank.css" media="all" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="all" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/version.1.0.css" media="all" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("random.styles", "/css/stylish")) => %(<link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />\n<link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("random.styles", "/elsewhere/file")) => %(<link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />\n<link href="/elsewhere/file.css" media="screen" rel="stylesheet" type="text/css" />),
%(stylesheet_link_tag("http://www.example.com/styles/style")) => %(<link href="http://www.example.com/styles/style.css" media="screen" rel="stylesheet" type="text/css" />)
}
......@@ -160,6 +161,20 @@ def test_javascript_include_tag_with_blank_asset_id
JavascriptIncludeToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
def test_javascript_include_tag_with_missing_source
assert_raise(Errno::ENOENT) {
javascript_include_tag('missing_security_guard')
}
assert_raise(Errno::ENOENT) {
javascript_include_tag(:defaults, 'missing_security_guard')
}
assert_nothing_raised {
javascript_include_tag('http://example.com/css/missing_security_guard')
}
end
def test_javascript_include_tag_with_given_asset_id
ENV["RAILS_ASSET_ID"] = "1"
assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
......@@ -167,26 +182,27 @@ def test_javascript_include_tag_with_given_asset_id
def test_register_javascript_include_default
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/slider.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_register_javascript_include_default_mixed_defaults
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'lib1', '/elsewhere/blub/lib2'
assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/slider.js" type="text/javascript"></script>\n<script src="/javascripts/lib1.js" type="text/javascript"></script>\n<script src="/elsewhere/blub/lib2.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'robber', '/elsewhere/cools.js'
assert_dom_equal %(<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/elsewhere/cools.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag(:defaults)
end
def test_custom_javascript_expansions
ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => ["head", "body", "tail"]
assert_dom_equal %(<script src="/javascripts/first.js" type="text/javascript"></script>\n<script src="/javascripts/head.js" type="text/javascript"></script>\n<script src="/javascripts/body.js" type="text/javascript"></script>\n<script src="/javascripts/tail.js" type="text/javascript"></script>\n<script src="/javascripts/last.js" type="text/javascript"></script>), javascript_include_tag('first', :monkey, 'last')
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"]
assert_dom_equal %(<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>), javascript_include_tag('controls', :robbery, 'effects')
end
def test_custom_javascript_expansions_and_defaults_puts_application_js_at_the_end
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_expansion :monkey => ["head", "body", "tail"]
assert_dom_equal %(<script src="/javascripts/first.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/head.js" type="text/javascript"></script>\n<script src="/javascripts/body.js" type="text/javascript"></script>\n<script src="/javascripts/tail.js" type="text/javascript"></script>\n<script src="/javascripts/last.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('first', :defaults, :monkey, 'last')
ActionView::Helpers::AssetTagHelper::register_javascript_expansion :robbery => ["bank", "robber"]
assert_dom_equal %(<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/prototype.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js" type="text/javascript"></script>\n<script src="/javascripts/controls.js" type="text/javascript"></script>\n<script src="/javascripts/bank.js" type="text/javascript"></script>\n<script src="/javascripts/robber.js" type="text/javascript"></script>\n<script src="/javascripts/effects.js" type="text/javascript"></script>\n<script src="/javascripts/application.js" type="text/javascript"></script>), javascript_include_tag('controls',:defaults, :robbery, 'effects')
end
def test_custom_javascript_expansions_with_undefined_symbol
......@@ -195,6 +211,7 @@ def test_custom_javascript_expansions_with_undefined_symbol
end
def test_stylesheet_path
ENV["RAILS_ASSET_ID"] = ""
StylePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
......@@ -207,9 +224,20 @@ def test_stylesheet_link_tag
StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
def test_stylesheet_link_tag_with_missing_source
assert_raise(Errno::ENOENT) {
stylesheet_link_tag('missing_security_guard')
}
assert_nothing_raised {
stylesheet_link_tag('http://example.com/css/missing_security_guard')
}
end
def test_custom_stylesheet_expansions
ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :monkey => ["head", "body", "tail"]
assert_dom_equal %(<link href="/stylesheets/first.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/last.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag('first', :monkey, 'last')
ENV["RAILS_ASSET_ID"] = ''
ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :robbery => ["bank", "robber"]
assert_dom_equal %(<link href="/stylesheets/version.1.0.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/bank.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/robber.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/subdir/subdir.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag('version.1.0', :robbery, 'subdir/subdir')
end
def test_custom_stylesheet_expansions_with_undefined_symbol
......@@ -546,8 +574,14 @@ def test_caching_stylesheet_link_tag_when_caching_on
stylesheet_link_tag(:all, :cache => true)
)
expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max
assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"]
expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max
assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
bytes_added_by_join = "\n\n".size * files_to_be_joined.size - "\n\n".size
expected_size = files_to_be_joined.sum { |p| File.size(p) } + bytes_added_by_join
assert_equal expected_size, File.size(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
assert_dom_equal(
%(<link href="http://a0.example.com/stylesheets/money.css" media="screen" rel="stylesheet" type="text/css" />),
......@@ -598,6 +632,28 @@ def test_concat_stylesheet_link_tag_when_caching_off
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::ASSETS_DIR, 'absolute'))
end
def test_caching_stylesheet_link_tag_when_caching_on_and_missing_css_file
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.asset_host = 'http://a0.example.com'
ActionController::Base.perform_caching = true
assert_raise(Errno::ENOENT) {
stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => true)
}
assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
assert_raise(Errno::ENOENT) {
stylesheet_link_tag('bank', 'robber', 'missing_security_guard', :cache => "money")
}
assert ! File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css'))
end
def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
......@@ -625,8 +681,10 @@ def test_caching_stylesheet_link_tag_with_relative_url_root
stylesheet_link_tag(:all, :cache => true)
)
expected = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/*.css"].map { |p| File.mtime(p) }.max
assert_equal expected, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
files_to_be_joined = Dir["#{ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR}/[^all]*.css"]
expected_mtime = files_to_be_joined.map { |p| File.mtime(p) }.max
assert_equal expected_mtime, File.mtime(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css'))
assert_dom_equal(
%(<link href="/collaboration/hieraki/stylesheets/money.css" media="screen" rel="stylesheet" type="text/css" />),
......
......@@ -67,6 +67,25 @@ class RecordNotSaved < ActiveRecordError
class StatementInvalid < ActiveRecordError
end
# Parent class for all specific exceptions which wrap database driver exceptions
# provides access to the original exception also.
class WrappedDatabaseException < StatementInvalid
attr_reader :original_exception
def initialize(message, original_exception)
super(message)
@original_exception, = original_exception
end
end
# Raised when a record cannot be inserted because it would violate a uniqueness constraint.
class RecordNotUnique < WrappedDatabaseException
end
# Raised when a record cannot be inserted or updated because it references a non-existent record.
class InvalidForeignKey < WrappedDatabaseException
end
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
# does not match number of expected variables.
#
......
......@@ -211,9 +211,14 @@ def log(sql, name)
@last_verification = 0
message = "#{e.class.name}: #{e.message}: #{sql}"
log_info(message, name, 0)
raise ActiveRecord::StatementInvalid, message
raise translate_exception(e, message)
end
def translate_exception(e, message)
# override in derived class
ActiveRecord::StatementInvalid.new(message)
end
def format_log_entry(message, dump = nil)
if ActiveRecord::Base.colorize_logging
if @@row_even
......
......@@ -563,6 +563,19 @@ def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
where_sql
end
protected
def translate_exception(exception, message)
case exception.errno
when 1062
RecordNotUnique.new(message, exception)
when 1452
InvalidForeignKey.new(message, exception)
else
super
end
end
private
def connect
encoding = @config[:encoding]
......
......@@ -941,6 +941,17 @@ def postgresql_version
end
end
def translate_exception(exception, message)
case exception.message
when /duplicate key value violates unique constraint/
RecordNotUnique.new(message, exception)
when /violates foreign key constraint/
InvalidForeignKey.new(message, exception)
else
super
end
end
private
# The internal PostgreSQL identifier of the money data type.
MONEY_COLUMN_TYPE_OID = 790 #:nodoc:
......
......@@ -431,6 +431,16 @@ def default_primary_key_type
'INTEGER PRIMARY KEY NOT NULL'.freeze
end
end
def translate_exception(exception, message)
case exception.message
when /column(s)? .* (is|are) not unique/
RecordNotUnique.new(message, exception)
else
super
end
end
end
class SQLite2Adapter < SQLiteAdapter # :nodoc:
......
......@@ -130,4 +130,19 @@ def test_add_limit_offset_should_sanitize_sql_injection_for_limit_with_comas
assert_equal " LIMIT 1,7 OFFSET 7", @connection.add_limit_offset!("", :limit=>sql_inject, :offset=>7)
end
end
def test_uniqueness_violations_are_translated_to_specific_exception
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
assert_raises(ActiveRecord::RecordNotUnique) do
@connection.execute "INSERT INTO subscribers(nick) VALUES('me')"
end
end
def test_foreign_key_violations_are_translated_to_specific_exception
unless @connection.adapter_name == 'SQLite'
assert_raises(ActiveRecord::InvalidForeignKey) do
@connection.execute "INSERT INTO fk_test_has_fk (fk_id) VALUES (0)"
end
end
end
end
......@@ -2,7 +2,12 @@
require 'active_support/core_ext/benchmark'
require 'active_support/core_ext/exception'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
%w(hash nil string time date date_time array big_decimal range object boolean).each do |library|
require "active_support/core_ext/#{library}/conversions"
end
# require 'active_support/core_ext' # FIXME: pulling in all to_param extensions
module ActiveSupport
# See ActiveSupport::Cache::Store for documentation.
......
......@@ -101,6 +101,7 @@ def self.default
def self.run(initializer = nil, config = nil)
default.config = config if config
default.config ||= Configuration.new
yield default.config if block_given?
default.run(initializer)
end
end
......@@ -176,7 +177,8 @@ def self.run(initializer = nil, config = nil)
# Action Pack, Action Mailer, and Active Resource) are loaded.
Initializer.default.add :require_frameworks do
begin
require 'active_support/all'
require 'active_support'
require 'active_support/core_ext/kernel/reporting'
configuration.frameworks.each { |framework| require(framework.to_s) }
rescue LoadError => e
# Re-raise as RuntimeError because Mongrel would swallow LoadError.
......@@ -396,12 +398,15 @@ def self.run(initializer = nil, config = nil)
end
Initializer.default.add :initialize_metal do
Rails::Rack::Metal.requested_metals = configuration.metals
Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
# TODO: Make Rails and metal work without ActionController
if defined?(ActionController)
Rails::Rack::Metal.requested_metals = configuration.metals
Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
configuration.middleware.insert_before(
:"ActionDispatch::ParamsParser",
Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
configuration.middleware.insert_before(
:"ActionDispatch::ParamsParser",
Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
end
end
# Add the load paths used by support functions such as the info controller
......
require 'action_controller/performance_test'
require 'action_controller/testing/performance_test'
ActionController::Base.perform_caching = true
ActiveSupport::Dependencies.mechanism = :require
......
......@@ -93,7 +93,6 @@ def framework_root_path
# TODO: Fix this when there is an application object
def middleware
require 'action_controller'
ActionController::Dispatcher.middleware
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册