diff options
-rw-r--r-- | actionview/CHANGELOG.md | 6 | ||||
-rw-r--r-- | actionview/lib/action_view/digestor.rb | 10 | ||||
-rw-r--r-- | actionview/test/fixtures/digestor/level/_recursion.html.erb | 1 | ||||
-rw-r--r-- | actionview/test/fixtures/digestor/level/recursion.html.erb | 1 | ||||
-rw-r--r-- | actionview/test/template/digestor_test.rb | 25 |
5 files changed, 40 insertions, 3 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 64393b4089..ba1c7936b3 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,9 @@ +* Fix "Stack Level Too Deep" error when redering recursive partials. + + Fixes #11340. + + *Rafael Mendonça França* + * Added an `enforce_utf8` hash option for `form_tag` method. Control to output a hidden input tag with name `utf8` without monkey diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 9324a1ac50..a674e4d7ea 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -7,10 +7,14 @@ module ActionView @@cache = ThreadSafe::Cache.new def self.digest(name, format, finder, options = {}) - cache_key = [name, format] + Array.wrap(options[:dependencies]) - @@cache[cache_key.join('.')] ||= begin + cache_key = ([name, format] + Array.wrap(options[:dependencies])).join('.') + @@cache.fetch(cache_key) do + @@cache[cache_key] ||= nil if options[:partial] # Prevent re-entry + klass = options[:partial] || name.include?("/_") ? PartialDigestor : Digestor - klass.new(name, format, finder, options).digest + digest = klass.new(name, format, finder, options).digest + + @@cache[cache_key] = digest # Store the value end end diff --git a/actionview/test/fixtures/digestor/level/_recursion.html.erb b/actionview/test/fixtures/digestor/level/_recursion.html.erb new file mode 100644 index 0000000000..ee5aaf09c3 --- /dev/null +++ b/actionview/test/fixtures/digestor/level/_recursion.html.erb @@ -0,0 +1 @@ +<%= render 'recursion' %> diff --git a/actionview/test/fixtures/digestor/level/recursion.html.erb b/actionview/test/fixtures/digestor/level/recursion.html.erb new file mode 100644 index 0000000000..ee5aaf09c3 --- /dev/null +++ b/actionview/test/fixtures/digestor/level/recursion.html.erb @@ -0,0 +1 @@ +<%= render 'recursion' %> diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index 06735c30d3..07f8d36d93 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -95,6 +95,31 @@ class TemplateDigestorTest < ActionView::TestCase end end + def test_recursion_in_renders + assert digest("level/recursion") # assert recursion is possible + assert_not_nil digest("level/recursion") # assert digest is stored + end + + def test_chaning_the_top_templete_on_recursion + assert digest("level/recursion") # assert recursion is possible + + assert_digest_difference("level/recursion") do + change_template("level/recursion") + end + + assert_not_nil digest("level/recursion") # assert digest is stored + end + + def test_chaning_the_partial_templete_on_recursion + assert digest("level/recursion") # assert recursion is possible + + assert_digest_difference("level/recursion") do + change_template("level/_recursion") + end + + assert_not_nil digest("level/recursion") # assert digest is stored + end + def test_dont_generate_a_digest_for_missing_templates assert_equal '', digest("nothing/there") end |