aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_view/paths.rb2
-rw-r--r--actionpack/lib/action_view/renderable.rb2
-rw-r--r--actionpack/lib/action_view/template.rb18
-rw-r--r--actionpack/test/template/compiled_templates_test.rb50
-rw-r--r--actionpack/test/template/render_test.rb26
5 files changed, 87 insertions, 11 deletions
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index f01ed9e6e0..ecb6103ade 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -102,7 +102,7 @@ module ActionView #:nodoc:
@paths = {}
templates_in_path do |template|
- template.freeze
+ template.load!
@paths[template.path] = template
@paths[template.path_without_extension] ||= template
end
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb
index c04399f2c9..7258ad04bf 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/renderable.rb
@@ -96,7 +96,7 @@ module ActionView
# The template will be compiled if the file has not been compiled yet, or
# if local_assigns has a new key, which isn't supported by the compiled code yet.
def recompile?(symbol)
- !(frozen? && Base::CompiledTemplates.method_defined?(symbol))
+ !Base::CompiledTemplates.method_defined?(symbol) || !loaded?
end
end
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index ca82454c0b..b486392ac4 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -57,6 +57,11 @@ module ActionView #:nodoc:
end
memoize :relative_path
+ def mtime
+ File.mtime(filename)
+ end
+ memoize :mtime
+
def source
File.read(filename)
end
@@ -79,6 +84,19 @@ module ActionView #:nodoc:
end
end
+ def stale?
+ File.mtime(filename) > mtime
+ end
+
+ def loaded?
+ @loaded
+ end
+
+ def load!
+ @loaded = true
+ freeze
+ end
+
private
def valid_extension?(extension)
Template.template_handler_extensions.include?(extension)
diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb
index 0b3d039409..a68b09bb45 100644
--- a/actionpack/test/template/compiled_templates_test.rb
+++ b/actionpack/test/template/compiled_templates_test.rb
@@ -30,9 +30,57 @@ uses_mocha 'TestTemplateRecompilation' do
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
end
+ def test_compiled_template_will_always_be_recompiled_when_template_is_not_cached
+ ActionView::Template.any_instance.expects(:loaded?).times(3).returns(false)
+ assert_equal 0, @compiled_templates.instance_methods.size
+ assert_equal "Hello world!", render(:file => "#{FIXTURE_LOAD_PATH}/test/hello_world.erb")
+ ActionView::Template.any_instance.expects(:compile!).times(3)
+ 3.times { assert_equal "Hello world!", render(:file => "#{FIXTURE_LOAD_PATH}/test/hello_world.erb") }
+ assert_equal 1, @compiled_templates.instance_methods.size
+ end
+
+ def test_template_changes_are_not_reflected_with_cached_templates
+ assert_equal "Hello world!", render(:file => "test/hello_world.erb")
+ modify_template "test/hello_world.erb", "Goodbye world!" do
+ assert_equal "Hello world!", render(:file => "test/hello_world.erb")
+ end
+ assert_equal "Hello world!", render(:file => "test/hello_world.erb")
+ end
+
+ def test_template_changes_are_reflected_with_uncached_templates
+ assert_equal "Hello world!", render_without_cache(:file => "test/hello_world.erb")
+ modify_template "test/hello_world.erb", "Goodbye world!" do
+ assert_equal "Goodbye world!", render_without_cache(:file => "test/hello_world.erb")
+ end
+ assert_equal "Hello world!", render_without_cache(:file => "test/hello_world.erb")
+ end
+
private
def render(*args)
- ActionView::Base.new(ActionController::Base.view_paths, {}).render(*args)
+ render_with_cache(*args)
+ end
+
+ def render_with_cache(*args)
+ view_paths = ActionController::Base.view_paths
+ assert view_paths.first.loaded?
+ ActionView::Base.new(view_paths, {}).render(*args)
+ end
+
+ def render_without_cache(*args)
+ view_paths = ActionView::Base.process_view_paths(FIXTURE_LOAD_PATH)
+ assert !view_paths.first.loaded?
+ ActionView::Base.new(view_paths, {}).render(*args)
+ end
+
+ def modify_template(template, content)
+ filename = "#{FIXTURE_LOAD_PATH}/#{template}"
+ old_content = File.read(filename)
+ begin
+ File.open(filename, "wb+") { |f| f.write(content) }
+ yield
+ ensure
+ File.open(filename, "wb+") { |f| f.write(old_content) }
+ end
end
end
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 28d38b0c76..9e827abbca 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -1,12 +1,10 @@
require 'abstract_unit'
require 'controller/fake_models'
-class ViewRenderTest < Test::Unit::TestCase
- def setup
+module RenderTestCases
+ def setup_view(paths)
@assigns = { :secret => 'in the sauce' }
- view_paths = ActionController::Base.view_paths
- @view = ActionView::Base.new(view_paths, @assigns)
- assert view_paths.first.loaded?
+ @view = ActionView::Base.new(paths, @assigns)
end
def test_render_file
@@ -199,13 +197,25 @@ class ViewRenderTest < Test::Unit::TestCase
end
end
-class LazyViewRenderTest < ViewRenderTest
+class CachedViewRenderTest < Test::Unit::TestCase
+ include RenderTestCases
+
+ # Ensure view path cache is primed
+ def setup
+ view_paths = ActionController::Base.view_paths
+ assert view_paths.first.loaded?
+ setup_view(view_paths)
+ end
+end
+
+class LazyViewRenderTest < Test::Unit::TestCase
+ include RenderTestCases
+
# Test the same thing as above, but make sure the view path
# is not eager loaded
def setup
- @assigns = { :secret => 'in the sauce' }
view_paths = ActionView::Base.process_view_paths(FIXTURE_LOAD_PATH)
- @view = ActionView::Base.new(view_paths, @assigns)
assert !view_paths.first.loaded?
+ setup_view(view_paths)
end
end