aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md18
-rw-r--r--actionview/lib/action_view/file_template.rb2
-rw-r--r--actionview/lib/action_view/renderer/streaming_template_renderer.rb2
-rw-r--r--actionview/lib/action_view/renderer/template_renderer.rb12
-rw-r--r--actionview/lib/action_view/template.rb13
-rw-r--r--actionview/lib/action_view/template/error.rb24
-rw-r--r--actionview/lib/action_view/template/file.rb28
-rw-r--r--actionview/lib/action_view/template/resolver.rb50
-rw-r--r--actionview/test/actionpack/abstract/abstract_controller_test.rb10
-rw-r--r--actionview/test/actionpack/abstract/render_test.rb2
-rw-r--r--actionview/test/actionpack/controller/layout_test.rb4
-rw-r--r--actionview/test/actionpack/controller/render_test.rb44
-rw-r--r--actionview/test/fixtures/actionpack/test/hello.builder2
-rw-r--r--actionview/test/fixtures/test/hello.builder2
-rw-r--r--actionview/test/fixtures/test/layout_render_file.erb2
-rw-r--r--actionview/test/fixtures/test/syntax_error.html.erb4
-rw-r--r--actionview/test/template/compiled_templates_test.rb26
-rw-r--r--actionview/test/template/log_subscriber_test.rb13
-rw-r--r--actionview/test/template/render_test.rb89
-rw-r--r--actionview/test/template/resolver_patterns_test.rb5
-rw-r--r--actionview/test/template/streaming_render_test.rb4
-rw-r--r--actionview/test/template/test_case_test.rb4
-rw-r--r--actionview/test/template/translation_helper_test.rb8
23 files changed, 237 insertions, 131 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index d07794ddf3..17a5782f9f 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,22 +1,32 @@
## Rails 6.0.0.beta3 (March 11, 2019) ##
-* No changes.
+* Only accept formats from registered mime types
+
+ A lack of filtering on mime types could allow an attacker to read
+ arbitrary files on the target server or to perform a denial of service
+ attack.
+
+ Fixes CVE-2019-5418
+ Fixes CVE-2019-5419
+
+ *John Hawthorn*, *Eileen M. Uchitelle*, *Aaron Patterson*
## Rails 6.0.0.beta2 (February 25, 2019) ##
-* ActionView::Template.finalize_compiled_template_methods is deprecated with
+* `ActionView::Template.finalize_compiled_template_methods` is deprecated with
no replacement.
*tenderlove*
-* config.action_view.finalize_compiled_template_methods is deprecated with
+* `config.action_view.finalize_compiled_template_methods` is deprecated with
no replacement.
*tenderlove*
* Ensure unique DOM IDs for collection inputs with float values.
- Fixes #34974
+
+ Fixes #34974.
*Mark Edmondson*
diff --git a/actionview/lib/action_view/file_template.rb b/actionview/lib/action_view/file_template.rb
index dea02176eb..e0dc7da3b6 100644
--- a/actionview/lib/action_view/file_template.rb
+++ b/actionview/lib/action_view/file_template.rb
@@ -11,7 +11,7 @@ module ActionView
end
def source
- File.binread @filename
+ ::File.binread @filename
end
def refresh(_)
diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
index 279ef3c680..19fa399e2c 100644
--- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb
+++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
@@ -34,7 +34,7 @@ module ActionView
return unless logger
message = +"\n#{exception.class} (#{exception.message}):\n"
- message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
+ message << exception.annotated_source_code.to_s if exception.respond_to?(:annotated_source_code)
message << " " << exception.backtrace.join("\n ")
logger.fatal("#{message}\n\n")
end
diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb
index 83b990b081..698f535b49 100644
--- a/actionview/lib/action_view/renderer/template_renderer.rb
+++ b/actionview/lib/action_view/renderer/template_renderer.rb
@@ -26,7 +26,12 @@ module ActionView
elsif options.key?(:html)
Template::HTML.new(options[:html], formats.first)
elsif options.key?(:file)
- @lookup_context.with_fallbacks.find_file(options[:file], nil, false, keys, @details)
+ if File.exist?(options[:file])
+ Template::File.new(options[:file])
+ else
+ ActiveSupport::Deprecation.warn "render file: should be given the absolute path to a file"
+ @lookup_context.with_fallbacks.find_file(options[:file], nil, false, keys, @details)
+ end
elsif options.key?(:inline)
handler = Template.handler_for_extension(options[:type] || "erb")
format = if handler.respond_to?(:default_format)
@@ -49,14 +54,14 @@ module ActionView
# Renders the given template. A string representing the layout can be
# supplied as well.
def render_template(view, template, layout_name, locals)
- render_with_layout(view, layout_name, template, locals) do |layout|
+ render_with_layout(view, template, layout_name, locals) do |layout|
instrument(:template, identifier: template.identifier, layout: layout.try(:virtual_path)) do
template.render(view, locals) { |*name| view._layout_for(*name) }
end
end
end
- def render_with_layout(view, path, template, locals)
+ def render_with_layout(view, template, path, locals)
layout = path && find_layout(path, locals.keys, [formats.first])
content = yield(layout)
@@ -84,6 +89,7 @@ module ActionView
when String
begin
if layout.start_with?("/")
+ ActiveSupport::Deprecation.warn "Rendering layouts from an absolute path is deprecated."
@lookup_context.with_fallbacks.find_template(layout, nil, false, [], details)
else
@lookup_context.find_template(layout, nil, false, [], details)
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb
index 6e3af1536a..ebe52532d6 100644
--- a/actionview/lib/action_view/template.rb
+++ b/actionview/lib/action_view/template.rb
@@ -113,6 +113,7 @@ module ActionView
eager_autoload do
autoload :Error
+ autoload :File
autoload :Handlers
autoload :HTML
autoload :Inline
@@ -139,7 +140,7 @@ module ActionView
@virtual_path = virtual_path
@variable = if @virtual_path
- base = @virtual_path[-1] == "/" ? "" : File.basename(@virtual_path)
+ base = @virtual_path[-1] == "/" ? "" : ::File.basename(@virtual_path)
base =~ /\A_?(.*?)(?:\.\w+)*\z/
$1.to_sym
end
@@ -331,6 +332,7 @@ module ActionView
# Make sure that the resulting String to be eval'd is in the
# encoding of the code
+ original_source = source
source = +<<-end_src
def #{method_name}(local_assigns, output_buffer)
@virtual_path = #{@virtual_path.inspect};#{locals_code};#{code}
@@ -351,7 +353,14 @@ module ActionView
raise WrongEncodingError.new(source, Encoding.default_internal)
end
- mod.module_eval(source, identifier, 0)
+ begin
+ mod.module_eval(source, identifier, 0)
+ rescue SyntaxError
+ # Account for when code in the template is not syntactically valid; e.g. if we're using
+ # ERB and the user writes <%= foo( %>, attempting to call a helper `foo` and interpolate
+ # the result into the template, but missing an end parenthesis.
+ raise SyntaxErrorInTemplate.new(self, original_source)
+ end
end
def handle_render_error(view, e)
diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb
index 4e3c02e05e..aace0be04d 100644
--- a/actionview/lib/action_view/template/error.rb
+++ b/actionview/lib/action_view/template/error.rb
@@ -104,12 +104,12 @@ module ActionView
def line_number
@line_number ||=
if file_name
- regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
+ regexp = /#{Regexp.escape ::File.basename(file_name)}:(\d+)/
$1 if message =~ regexp || backtrace.find { |line| line =~ regexp }
end
end
- def annoted_source_code
+ def annotated_source_code
source_extract(4)
end
@@ -138,4 +138,24 @@ module ActionView
end
TemplateError = Template::Error
+
+ class SyntaxErrorInTemplate < TemplateError #:nodoc
+ def initialize(template, offending_code_string)
+ @offending_code_string = offending_code_string
+ super(template)
+ end
+
+ def message
+ <<~MESSAGE
+ Encountered a syntax error while rendering template: check #{@offending_code_string}
+ MESSAGE
+ end
+
+ def annotated_source_code
+ @offending_code_string.split("\n").map.with_index(1) { |line, index|
+ indentation = " " * 4
+ "#{index}:#{indentation}#{line}"
+ }
+ end
+ end
end
diff --git a/actionview/lib/action_view/template/file.rb b/actionview/lib/action_view/template/file.rb
new file mode 100644
index 0000000000..487e5735cf
--- /dev/null
+++ b/actionview/lib/action_view/template/file.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module ActionView #:nodoc:
+ # = Action View File Template
+ class Template #:nodoc:
+ class File #:nodoc:
+ attr_accessor :type, :format
+
+ def initialize(filename)
+ @filename = filename.to_s
+ extname = ::File.extname(filename).delete(".")
+ @type = Template::Types[extname] || Template::Types[:text]
+ @format = @type.symbol
+ end
+
+ def identifier
+ @filename
+ end
+
+ def render(*args)
+ ::File.read(@filename)
+ end
+
+ def formats; Array(format); end
+ deprecate :formats
+ end
+ end
+end
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index 1c577348e5..3b4c8a94bc 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -168,7 +168,12 @@ module ActionView
DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}"
def initialize(pattern = nil)
- @pattern = pattern || DEFAULT_PATTERN
+ if pattern
+ ActiveSupport::Deprecation.warn "Specifying a custom path for #{self.class} is deprecated. Implement a custom Resolver subclass instead."
+ @pattern = pattern
+ else
+ @pattern = DEFAULT_PATTERN
+ end
super()
end
@@ -273,44 +278,7 @@ module ActionView
end
end
- # A resolver that loads files from the filesystem. It allows setting your own
- # resolving pattern. Such pattern can be a glob string supported by some variables.
- #
- # ==== Examples
- #
- # Default pattern, loads views the same way as previous versions of rails, eg. when you're
- # looking for <tt>users/new</tt> it will produce query glob: <tt>users/new{.{en},}{.{html,js},}{.{erb,haml},}</tt>
- #
- # FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
- #
- # This one allows you to keep files with different formats in separate subdirectories,
- # eg. <tt>users/new.html</tt> will be loaded from <tt>users/html/new.erb</tt> or <tt>users/new.html.erb</tt>,
- # <tt>users/new.js</tt> from <tt>users/js/new.erb</tt> or <tt>users/new.js.erb</tt>, etc.
- #
- # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
- #
- # If you don't specify a pattern then the default will be used.
- #
- # In order to use any of the customized resolvers above in a Rails application, you just need
- # to configure ActionController::Base.view_paths in an initializer, for example:
- #
- # ActionController::Base.view_paths = FileSystemResolver.new(
- # Rails.root.join("app/views"),
- # ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}",
- # )
- #
- # ==== Pattern format and variables
- #
- # Pattern has to be a valid glob string, and it allows you to use the
- # following variables:
- #
- # * <tt>:prefix</tt> - usually the controller path
- # * <tt>:action</tt> - name of the action
- # * <tt>:locale</tt> - possible locale versions
- # * <tt>:formats</tt> - possible request formats (for example html, json, xml...)
- # * <tt>:variants</tt> - possible request variants (for example phone, tablet...)
- # * <tt>:handlers</tt> - possible handlers (for example erb, haml, builder...)
- #
+ # A resolver that loads files from the filesystem.
class FileSystemResolver < PathResolver
def initialize(path, pattern = nil)
raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
@@ -331,6 +299,10 @@ module ActionView
# An Optimized resolver for Rails' most common case.
class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
+ def initialize(path)
+ super(path)
+ end
+
private
def find_template_paths_from_details(path, details)
diff --git a/actionview/test/actionpack/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb
index 4d4e2b8ef2..eecc19d413 100644
--- a/actionview/test/actionpack/abstract/abstract_controller_test.rb
+++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb
@@ -229,11 +229,11 @@ module AbstractController
end
class ActionMissingRespondToActionController < AbstractController::Base
- # No actions
- private
- def action_missing(action_name)
- self.response_body = "success"
- end
+ # No actions
+ private
+ def action_missing(action_name)
+ self.response_body = "success"
+ end
end
class RespondToActionController < AbstractController::Base
diff --git a/actionview/test/actionpack/abstract/render_test.rb b/actionview/test/actionpack/abstract/render_test.rb
index d863548a5c..e4e8ac93b2 100644
--- a/actionview/test/actionpack/abstract/render_test.rb
+++ b/actionview/test/actionpack/abstract/render_test.rb
@@ -26,7 +26,7 @@ module AbstractController
end
def file
- render file: "some/file"
+ ActiveSupport::Deprecation.silence { render file: "some/file" }
end
def inline
diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb
index 838b564c5d..f946e4360d 100644
--- a/actionview/test/actionpack/controller/layout_test.rb
+++ b/actionview/test/actionpack/controller/layout_test.rb
@@ -233,7 +233,9 @@ class LayoutSetInResponseTest < ActionController::TestCase
def test_absolute_pathed_layout
@controller = AbsolutePathLayoutController.new
- get :hello
+ assert_deprecated do
+ get :hello
+ end
assert_equal "layout_test.erb hello.erb", @response.body.strip
end
end
diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb
index 52c3c54d96..c8ce7366d1 100644
--- a/actionview/test/actionpack/controller/render_test.rb
+++ b/actionview/test/actionpack/controller/render_test.rb
@@ -872,48 +872,64 @@ class RenderTest < ActionController::TestCase
# :ported:
def test_render_file_with_instance_variables
- get :render_file_with_instance_variables
+ assert_deprecated do
+ get :render_file_with_instance_variables
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
def test_render_file
- get :hello_world_file
+ assert_deprecated do
+ get :hello_world_file
+ end
assert_equal "Hello world!", @response.body
end
# :ported:
def test_render_file_not_using_full_path
- get :render_file_not_using_full_path
+ assert_deprecated do
+ get :render_file_not_using_full_path
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
# :ported:
def test_render_file_not_using_full_path_with_dot_in_path
- get :render_file_not_using_full_path_with_dot_in_path
+ assert_deprecated do
+ get :render_file_not_using_full_path_with_dot_in_path
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
# :ported:
def test_render_file_using_pathname
- get :render_file_using_pathname
+ assert_deprecated do
+ get :render_file_using_pathname
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
# :ported:
def test_render_file_with_locals
- get :render_file_with_locals
+ assert_deprecated do
+ get :render_file_with_locals
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
# :ported:
def test_render_file_as_string_with_locals
- get :render_file_as_string_with_locals
+ assert_deprecated do
+ get :render_file_as_string_with_locals
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
# :assessed:
def test_render_file_from_template
- get :render_file_from_template
+ assert_deprecated do
+ get :render_file_from_template
+ end
assert_equal "The secret is in the sauce\n", @response.body
end
@@ -1133,11 +1149,19 @@ class RenderTest < ActionController::TestCase
end
def test_bad_render_to_string_still_throws_exception
- assert_raise(ActionView::MissingTemplate) { get :render_to_string_with_exception }
+ assert_deprecated do
+ assert_raise(ActionView::MissingTemplate) do
+ get :render_to_string_with_exception
+ end
+ end
end
def test_render_to_string_that_throws_caught_exception_doesnt_break_assigns
- assert_nothing_raised { get :render_to_string_with_caught_exception }
+ assert_deprecated do
+ assert_nothing_raised do
+ get :render_to_string_with_caught_exception
+ end
+ end
assert_equal "i'm before the render", @controller.instance_variable_get(:@before)
assert_equal "i'm after the render", @controller.instance_variable_get(:@after)
end
diff --git a/actionview/test/fixtures/actionpack/test/hello.builder b/actionview/test/fixtures/actionpack/test/hello.builder
index b8ab17ad5b..4c34ee85f0 100644
--- a/actionview/test/fixtures/actionpack/test/hello.builder
+++ b/actionview/test/fixtures/actionpack/test/hello.builder
@@ -1,4 +1,4 @@
xml.html do
xml.p "Hello #{@name}"
- xml << render(file: "test/greeting")
+ xml << render(template: "test/greeting")
end
diff --git a/actionview/test/fixtures/test/hello.builder b/actionview/test/fixtures/test/hello.builder
index b8ab17ad5b..4c34ee85f0 100644
--- a/actionview/test/fixtures/test/hello.builder
+++ b/actionview/test/fixtures/test/hello.builder
@@ -1,4 +1,4 @@
xml.html do
xml.p "Hello #{@name}"
- xml << render(file: "test/greeting")
+ xml << render(template: "test/greeting")
end
diff --git a/actionview/test/fixtures/test/layout_render_file.erb b/actionview/test/fixtures/test/layout_render_file.erb
index 2f8e921c5f..0477743dc4 100644
--- a/actionview/test/fixtures/test/layout_render_file.erb
+++ b/actionview/test/fixtures/test/layout_render_file.erb
@@ -1,2 +1,2 @@
<% content_for :title do %>title<% end -%>
-<%= render :file => 'layouts/yield' -%> \ No newline at end of file
+<%= render template: 'layouts/yield' -%>
diff --git a/actionview/test/fixtures/test/syntax_error.html.erb b/actionview/test/fixtures/test/syntax_error.html.erb
new file mode 100644
index 0000000000..4004a2b187
--- /dev/null
+++ b/actionview/test/fixtures/test/syntax_error.html.erb
@@ -0,0 +1,4 @@
+<%= foo(
+ 1,
+ 2,
+%>
diff --git a/actionview/test/template/compiled_templates_test.rb b/actionview/test/template/compiled_templates_test.rb
index 6375555bb4..d7f2e8ee07 100644
--- a/actionview/test/template/compiled_templates_test.rb
+++ b/actionview/test/template/compiled_templates_test.rb
@@ -24,7 +24,7 @@ class CompiledTemplatesTest < ActiveSupport::TestCase
def test_template_with_ruby_keyword_locals
assert_equal "The class is foo",
- render(file: "test/render_file_with_ruby_keyword_locals", locals: { class: "foo" })
+ render(template: "test/render_file_with_ruby_keyword_locals", locals: { class: "foo" })
end
def test_template_with_invalid_identifier_locals
@@ -34,7 +34,7 @@ class CompiledTemplatesTest < ActiveSupport::TestCase
"d-a-s-h-e-s": "",
"white space": "",
}
- assert_equal locals.inspect, render(file: "test/render_file_inspect_local_assigns", locals: locals)
+ assert_equal locals.inspect, render(template: "test/render_file_inspect_local_assigns", locals: locals)
end
def test_template_with_delegation_reserved_keywords
@@ -44,36 +44,36 @@ class CompiledTemplatesTest < ActiveSupport::TestCase
args: "three",
block: "four",
}
- assert_equal "one two three four", render(file: "test/test_template_with_delegation_reserved_keywords", locals: locals)
+ assert_equal "one two three four", render(template: "test/test_template_with_delegation_reserved_keywords", locals: locals)
end
def test_template_with_unicode_identifier
- assert_equal "๐ŸŽ‚", render(file: "test/render_file_unicode_local", locals: { ๐ŸŽƒ: "๐ŸŽ‚" })
+ assert_equal "๐ŸŽ‚", render(template: "test/render_file_unicode_local", locals: { ๐ŸŽƒ: "๐ŸŽ‚" })
end
def test_template_with_instance_variable_identifier
- assert_equal "bar", render(file: "test/render_file_instance_variable", locals: { "@foo": "bar" })
+ assert_equal "bar", render(template: "test/render_file_instance_variable", locals: { "@foo": "bar" })
end
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
- assert_equal "one", render(file: "test/render_file_with_locals_and_default")
- assert_equal "two", render(file: "test/render_file_with_locals_and_default", locals: { secret: "two" })
+ assert_equal "one", render(template: "test/render_file_with_locals_and_default")
+ assert_equal "two", render(template: "test/render_file_with_locals_and_default", locals: { secret: "two" })
end
def test_template_changes_are_not_reflected_with_cached_templates
- assert_equal "Hello world!", render(file: "test/hello_world")
+ assert_equal "Hello world!", render(template: "test/hello_world")
modify_template "test/hello_world.erb", "Goodbye world!" do
- assert_equal "Hello world!", render(file: "test/hello_world")
+ assert_equal "Hello world!", render(template: "test/hello_world")
end
- assert_equal "Hello world!", render(file: "test/hello_world")
+ assert_equal "Hello world!", render(template: "test/hello_world")
end
def test_template_changes_are_reflected_with_uncached_templates
- assert_equal "Hello world!", render_without_cache(file: "test/hello_world")
+ assert_equal "Hello world!", render_without_cache(template: "test/hello_world")
modify_template "test/hello_world.erb", "Goodbye world!" do
- assert_equal "Goodbye world!", render_without_cache(file: "test/hello_world")
+ assert_equal "Goodbye world!", render_without_cache(template: "test/hello_world")
end
- assert_equal "Hello world!", render_without_cache(file: "test/hello_world")
+ assert_equal "Hello world!", render_without_cache(template: "test/hello_world")
end
private
diff --git a/actionview/test/template/log_subscriber_test.rb b/actionview/test/template/log_subscriber_test.rb
index 85735139c1..8b160a7336 100644
--- a/actionview/test/template/log_subscriber_test.rb
+++ b/actionview/test/template/log_subscriber_test.rb
@@ -51,9 +51,20 @@ class AVLogSubscriberTest < ActiveSupport::TestCase
def @view.combined_fragment_cache_key(*); "ahoy `controller` dependency"; end
end
+ def test_render_template_template
+ Rails.stub(:root, File.expand_path(FIXTURE_LOAD_PATH)) do
+ @view.render(template: "test/hello_world")
+ wait
+
+ assert_equal 2, @logger.logged(:info).size
+ assert_match(/Rendering test\/hello_world\.erb/, @logger.logged(:info).first)
+ assert_match(/Rendered test\/hello_world\.erb/, @logger.logged(:info).last)
+ end
+ end
+
def test_render_file_template
Rails.stub(:root, File.expand_path(FIXTURE_LOAD_PATH)) do
- @view.render(file: "test/hello_world")
+ @view.render(file: "#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
wait
assert_equal 2, @logger.logged(:info).size
diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb
index 1f6dbfc4a5..15c41051de 100644
--- a/actionview/test/template/render_test.rb
+++ b/actionview/test/template/render_test.rb
@@ -53,20 +53,26 @@ module RenderTestCases
assert_match(/You invoked render but did not give any of (.+) option\./, e.message)
end
+ def test_render_template
+ assert_equal "Hello world!", @view.render(template: "test/hello_world")
+ end
+
+
def test_render_file
- assert_equal "Hello world!", @view.render(file: "test/hello_world")
+ assert_equal "Hello world!", assert_deprecated { @view.render(file: "test/hello_world") }
end
# Test if :formats, :locale etc. options are passed correctly to the resolvers.
def test_render_file_with_format
- assert_match "<h1>No Comment</h1>", @view.render(file: "comments/empty", formats: [:html])
- assert_match "<error>No Comment</error>", @view.render(file: "comments/empty", formats: [:xml])
- assert_match "<error>No Comment</error>", @view.render(file: "comments/empty", formats: :xml)
+ assert_match "<h1>No Comment</h1>", assert_deprecated { @view.render(file: "comments/empty", formats: [:html]) }
+ assert_match "<error>No Comment</error>", assert_deprecated { @view.render(file: "comments/empty", formats: [:xml]) }
+ assert_match "<error>No Comment</error>", assert_deprecated { @view.render(file: "comments/empty", formats: :xml) }
end
def test_render_template_with_format
assert_match "<h1>No Comment</h1>", @view.render(template: "comments/empty", formats: [:html])
assert_match "<error>No Comment</error>", @view.render(template: "comments/empty", formats: [:xml])
+ assert_match "<error>No Comment</error>", @view.render(template: "comments/empty", formats: :xml)
end
def test_render_partial_implicitly_use_format_of_the_rendered_template
@@ -93,8 +99,8 @@ module RenderTestCases
end
def test_render_file_with_locale
- assert_equal "<h1>Kein Kommentar</h1>", @view.render(file: "comments/empty", locale: [:de])
- assert_equal "<h1>Kein Kommentar</h1>", @view.render(file: "comments/empty", locale: :de)
+ assert_equal "<h1>Kein Kommentar</h1>", assert_deprecated { @view.render(file: "comments/empty", locale: [:de]) }
+ assert_equal "<h1>Kein Kommentar</h1>", assert_deprecated { @view.render(file: "comments/empty", locale: :de) }
end
def test_render_template_with_locale
@@ -106,8 +112,8 @@ module RenderTestCases
end
def test_render_file_with_handlers
- assert_equal "<h1>No Comment</h1>\n", @view.render(file: "comments/empty", handlers: [:builder])
- assert_equal "<h1>No Comment</h1>\n", @view.render(file: "comments/empty", handlers: :builder)
+ assert_equal "<h1>No Comment</h1>\n", assert_deprecated { @view.render(file: "comments/empty", handlers: [:builder]) }
+ assert_equal "<h1>No Comment</h1>\n", assert_deprecated { @view.render(file: "comments/empty", handlers: :builder) }
end
def test_render_template_with_handlers
@@ -124,7 +130,7 @@ module RenderTestCases
def test_render_raw_is_html_safe_and_does_not_escape_output
buffer = ActiveSupport::SafeBuffer.new
- buffer << @view.render(file: "plain_text")
+ buffer << @view.render(template: "plain_text")
assert_equal true, buffer.html_safe?
assert_equal buffer, "<%= hello_world %>\n"
end
@@ -137,40 +143,45 @@ module RenderTestCases
assert_equal "4", @view.render(inline: "(2**2).to_s", type: :ruby)
end
- def test_render_file_with_localization_on_context_level
+ def test_render_template_with_localization_on_context_level
old_locale, @view.locale = @view.locale, :da
- assert_equal "Hey verden", @view.render(file: "test/hello_world")
+ assert_equal "Hey verden", @view.render(template: "test/hello_world")
ensure
@view.locale = old_locale
end
- def test_render_file_with_dashed_locale
+ def test_render_template_with_dashed_locale
old_locale, @view.locale = @view.locale, :"pt-BR"
- assert_equal "Ola mundo", @view.render(file: "test/hello_world")
+ assert_equal "Ola mundo", @view.render(template: "test/hello_world")
ensure
@view.locale = old_locale
end
- def test_render_file_at_top_level
- assert_equal "Elastica", @view.render(file: "/shared")
+ def test_render_template_at_top_level
+ assert_equal "Elastica", @view.render(template: "/shared")
end
- def test_render_file_with_full_path
+ def test_render_file_with_full_path_no_extension
template_path = File.expand_path("../fixtures/test/hello_world", __dir__)
+ assert_equal "Hello world!", assert_deprecated { @view.render(file: template_path) }
+ end
+
+ def test_render_file_with_full_path
+ template_path = File.expand_path("../fixtures/test/hello_world.erb", __dir__)
assert_equal "Hello world!", @view.render(file: template_path)
end
def test_render_file_with_instance_variables
- assert_equal "The secret is in the sauce\n", @view.render(file: "test/render_file_with_ivar")
+ assert_equal "The secret is in the sauce\n", assert_deprecated { @view.render(file: "test/render_file_with_ivar") }
end
def test_render_file_with_locals
locals = { secret: "in the sauce" }
- assert_equal "The secret is in the sauce\n", @view.render(file: "test/render_file_with_locals", locals: locals)
+ assert_equal "The secret is in the sauce\n", assert_deprecated { @view.render(file: "test/render_file_with_locals", locals: locals) }
end
def test_render_file_not_using_full_path_with_dot_in_path
- assert_equal "The secret is in the sauce\n", @view.render(file: "test/dot.directory/render_file_with_ivar")
+ assert_equal "The secret is in the sauce\n", assert_deprecated { @view.render(file: "test/dot.directory/render_file_with_ivar") }
end
def test_render_partial_from_default
@@ -258,18 +269,24 @@ module RenderTestCases
"and is followed by any combination of letters, numbers and underscores.", e.message
end
+ def test_render_template_with_syntax_error
+ e = assert_raises(ActionView::Template::Error) { @view.render(template: "test/syntax_error") }
+ assert_match %r!syntax!, e.message
+ assert_equal "1: <%= foo(", e.annotated_source_code[0].strip
+ end
+
def test_render_partial_with_errors
e = assert_raises(ActionView::Template::Error) { @view.render(partial: "test/raise") }
assert_match %r!method.*doesnt_exist!, e.message
assert_equal "", e.sub_template_message
assert_equal "1", e.line_number
- assert_equal "1: <%= doesnt_exist %>", e.annoted_source_code[0].strip
+ assert_equal "1: <%= doesnt_exist %>", e.annotated_source_code[0].strip
assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name
end
def test_render_error_indentation
e = assert_raises(ActionView::Template::Error) { @view.render(partial: "test/raise_indentation") }
- error_lines = e.annoted_source_code
+ error_lines = e.annotated_source_code
assert_match %r!error\shere!, e.message
assert_equal "11", e.line_number
assert_equal " 9: <p>Ninth paragraph</p>", error_lines.second
@@ -285,11 +302,11 @@ module RenderTestCases
end
def test_render_file_with_errors
- e = assert_raises(ActionView::Template::Error) { @view.render(file: File.expand_path("test/_raise", FIXTURE_LOAD_PATH)) }
+ e = assert_raises(ActionView::Template::Error) { assert_deprecated { @view.render(file: File.expand_path("test/_raise", FIXTURE_LOAD_PATH)) } }
assert_match %r!method.*doesnt_exist!, e.message
assert_equal "", e.sub_template_message
assert_equal "1", e.line_number
- assert_equal "1: <%= doesnt_exist %>", e.annoted_source_code[0].strip
+ assert_equal "1: <%= doesnt_exist %>", e.annotated_source_code[0].strip
assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name
end
@@ -369,7 +386,7 @@ module RenderTestCases
def test_without_compiled_method_container_is_deprecated
view = ActionView::Base.with_view_paths(ActionController::Base.view_paths)
assert_deprecated("ActionView::Base instances must implement `compiled_method_container`") do
- assert_equal "Hello world!", view.render(file: "test/hello_world")
+ assert_equal "Hello world!", view.render(template: "test/hello_world")
end
end
@@ -549,28 +566,28 @@ module RenderTestCases
def test_render_ignores_templates_with_malformed_template_handlers
%w(malformed malformed.erb malformed.html.erb malformed.en.html.erb).each do |name|
assert File.exist?(File.expand_path("#{FIXTURE_LOAD_PATH}/test/malformed/#{name}~")), "Malformed file (#{name}~) which should be ignored does not exists"
- assert_raises(ActionView::MissingTemplate) { @view.render(file: "test/malformed/#{name}") }
+ assert_raises(ActionView::MissingTemplate) { @view.render(template: "test/malformed/#{name}") }
end
end
def test_render_with_layout
assert_equal %(<title></title>\nHello world!\n),
- @view.render(file: "test/hello_world", layout: "layouts/yield")
+ @view.render(template: "test/hello_world", layout: "layouts/yield")
end
def test_render_with_layout_which_has_render_inline
assert_equal %(welcome\nHello world!\n),
- @view.render(file: "test/hello_world", layout: "layouts/yield_with_render_inline_inside")
+ @view.render(template: "test/hello_world", layout: "layouts/yield_with_render_inline_inside")
end
def test_render_with_layout_which_renders_another_partial
assert_equal %(partial html\nHello world!\n),
- @view.render(file: "test/hello_world", layout: "layouts/yield_with_render_partial_inside")
+ @view.render(template: "test/hello_world", layout: "layouts/yield_with_render_partial_inside")
end
def test_render_partial_with_html_only_extension
assert_equal %(<h1>partial html</h1>\nHello world!\n),
- @view.render(file: "test/hello_world", layout: "layouts/render_partial_html")
+ @view.render(template: "test/hello_world", layout: "layouts/render_partial_html")
end
def test_render_layout_with_block_and_yield
@@ -625,17 +642,17 @@ module RenderTestCases
def test_render_with_nested_layout
assert_equal %(<title>title</title>\n\n<div id="column">column</div>\n<div id="content">content</div>\n),
- @view.render(file: "test/nested_layout", layout: "layouts/yield")
+ @view.render(template: "test/nested_layout", layout: "layouts/yield")
end
def test_render_with_file_in_layout
assert_equal %(\n<title>title</title>\n\n),
- @view.render(file: "test/layout_render_file")
+ @view.render(template: "test/layout_render_file")
end
def test_render_layout_with_object
assert_equal %(<title>David</title>),
- @view.render(file: "test/layout_render_object")
+ @view.render(template: "test/layout_render_object")
end
def test_render_with_passing_couple_extensions_to_one_register_template_handler_function_call
@@ -687,7 +704,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase
def test_render_utf8_template_with_magic_comment
with_external_encoding Encoding::ASCII_8BIT do
- result = @view.render(file: "test/utf8_magic", formats: [:html], layouts: "layouts/yield")
+ result = @view.render(template: "test/utf8_magic", formats: [:html], layouts: "layouts/yield")
assert_equal Encoding::UTF_8, result.encoding
assert_equal "\nะ ัƒััะบะธะน \nั‚ะตะบัั‚\n\nUTF-8\nUTF-8\nUTF-8\n", result
end
@@ -695,7 +712,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase
def test_render_utf8_template_with_default_external_encoding
with_external_encoding Encoding::UTF_8 do
- result = @view.render(file: "test/utf8", formats: [:html], layouts: "layouts/yield")
+ result = @view.render(template: "test/utf8", formats: [:html], layouts: "layouts/yield")
assert_equal Encoding::UTF_8, result.encoding
assert_equal "ะ ัƒััะบะธะน ั‚ะตะบัั‚\n\nUTF-8\nUTF-8\nUTF-8\n", result
end
@@ -703,14 +720,14 @@ class LazyViewRenderTest < ActiveSupport::TestCase
def test_render_utf8_template_with_incompatible_external_encoding
with_external_encoding Encoding::SHIFT_JIS do
- e = assert_raises(ActionView::Template::Error) { @view.render(file: "test/utf8", formats: [:html], layouts: "layouts/yield") }
+ e = assert_raises(ActionView::Template::Error) { @view.render(template: "test/utf8", formats: [:html], layouts: "layouts/yield") }
assert_match "Your template was not saved as valid Shift_JIS", e.cause.message
end
end
def test_render_utf8_template_with_partial_with_incompatible_encoding
with_external_encoding Encoding::SHIFT_JIS do
- e = assert_raises(ActionView::Template::Error) { @view.render(file: "test/utf8_magic_with_bare_partial", formats: [:html], layouts: "layouts/yield") }
+ e = assert_raises(ActionView::Template::Error) { @view.render(template: "test/utf8_magic_with_bare_partial", formats: [:html], layouts: "layouts/yield") }
assert_match "Your template was not saved as valid Shift_JIS", e.cause.message
end
end
diff --git a/actionview/test/template/resolver_patterns_test.rb b/actionview/test/template/resolver_patterns_test.rb
index 8122de779f..22815c8dbe 100644
--- a/actionview/test/template/resolver_patterns_test.rb
+++ b/actionview/test/template/resolver_patterns_test.rb
@@ -6,7 +6,10 @@ class ResolverPatternsTest < ActiveSupport::TestCase
def setup
path = File.expand_path("../fixtures", __dir__)
pattern = ":prefix/{:formats/,}:action{.:formats,}{+:variants,}{.:handlers,}"
- @resolver = ActionView::FileSystemResolver.new(path, pattern)
+
+ assert_deprecated do
+ @resolver = ActionView::FileSystemResolver.new(path, pattern)
+ end
end
def test_should_return_empty_list_for_unknown_path
diff --git a/actionview/test/template/streaming_render_test.rb b/actionview/test/template/streaming_render_test.rb
index a5b59a700e..a5e673e71e 100644
--- a/actionview/test/template/streaming_render_test.rb
+++ b/actionview/test/template/streaming_render_test.rb
@@ -47,12 +47,12 @@ class FiberedTest < SetupFiberedBase
end
def test_render_file
- assert_equal "Hello world!", buffered_render(file: "test/hello_world")
+ assert_equal "Hello world!", assert_deprecated { buffered_render(file: "test/hello_world") }
end
def test_render_file_with_locals
locals = { secret: "in the sauce" }
- assert_equal "The secret is in the sauce\n", buffered_render(file: "test/render_file_with_locals", locals: locals)
+ assert_equal "The secret is in the sauce\n", assert_deprecated { buffered_render(file: "test/render_file_with_locals", locals: locals) }
end
def test_render_partial
diff --git a/actionview/test/template/test_case_test.rb b/actionview/test/template/test_case_test.rb
index c89aff9c9d..0b2a2a9911 100644
--- a/actionview/test/template/test_case_test.rb
+++ b/actionview/test/template/test_case_test.rb
@@ -284,7 +284,7 @@ module ActionView
@controller.controller_path = "test"
@customers = [DeveloperStruct.new("Eloy"), DeveloperStruct.new("Manfred")]
- assert_match(/Hello: EloyHello: Manfred/, render(file: "test/list"))
+ assert_match(/Hello: EloyHello: Manfred/, render(template: "test/list"))
end
test "is able to render partials from templates and also use instance variables after view has been referenced" do
@@ -293,7 +293,7 @@ module ActionView
view
@customers = [DeveloperStruct.new("Eloy"), DeveloperStruct.new("Manfred")]
- assert_match(/Hello: EloyHello: Manfred/, render(file: "test/list"))
+ assert_match(/Hello: EloyHello: Manfred/, render(template: "test/list"))
end
test "is able to use helpers that depend on the view flow" do
diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb
index 23fc9850c4..9afdc3c68f 100644
--- a/actionview/test/template/translation_helper_test.rb
+++ b/actionview/test/template/translation_helper_test.rb
@@ -127,20 +127,20 @@ class TranslationHelperTest < ActiveSupport::TestCase
end
def test_finds_translation_scoped_by_partial
- assert_equal "Foo", view.render(file: "translations/templates/found").strip
+ assert_equal "Foo", view.render(template: "translations/templates/found").strip
end
def test_finds_array_of_translations_scoped_by_partial
- assert_equal "Foo Bar", @view.render(file: "translations/templates/array").strip
+ assert_equal "Foo Bar", @view.render(template: "translations/templates/array").strip
end
def test_default_lookup_scoped_by_partial
- assert_equal "Foo", view.render(file: "translations/templates/default").strip
+ assert_equal "Foo", view.render(template: "translations/templates/default").strip
end
def test_missing_translation_scoped_by_partial
expected = '<span class="translation_missing" title="translation missing: en.translations.templates.missing.missing">Missing</span>'
- assert_equal expected, view.render(file: "translations/templates/missing").strip
+ assert_equal expected, view.render(template: "translations/templates/missing").strip
end
def test_translate_does_not_mark_plain_text_as_safe_html