1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/actionview/test/template/dependency_tracker_test.rb
João Britto c2afa05561 Improve ERB dependency detection.
The current implementation can't handle some special cases of oddly-formatted Ruby. Now we are able to detect them:

* Multi-line arguments on the `render` call
* Strings containing quotes, e.g. `"something's wrong"`
* Multiple kinds of identifiers - instance variables, class variables and globals
* Method chains as arguments for the `render` call

Also, this fix reduces the rate of "false positives" which showed up when we had calls/access to identifiers containing `render`, like `surrender` and `rendering`.
2014-01-09 20:36:59 -02:00

158 lines
4.7 KiB
Ruby

# encoding: utf-8
require 'abstract_unit'
require 'action_view/dependency_tracker'
class NeckbeardTracker
def self.call(name, template)
["foo/#{name}"]
end
end
class FakeTemplate
attr_reader :source, :handler
def initialize(source, handler = Neckbeard)
@source, @handler = source, handler
end
end
Neckbeard = lambda {|template| template.source }
Bowtie = lambda {|template| template.source }
class DependencyTrackerTest < ActionView::TestCase
def tracker
ActionView::DependencyTracker
end
def setup
ActionView::Template.register_template_handler :neckbeard, Neckbeard
tracker.register_tracker(:neckbeard, NeckbeardTracker)
end
def teardown
tracker.remove_tracker(:neckbeard)
end
def test_finds_tracker_by_template_handler
template = FakeTemplate.new("boo/hoo")
dependencies = tracker.find_dependencies("boo/hoo", template)
assert_equal ["foo/boo/hoo"], dependencies
end
def test_returns_empty_array_if_no_tracker_is_found
template = FakeTemplate.new("boo/hoo", Bowtie)
dependencies = tracker.find_dependencies("boo/hoo", template)
assert_equal [], dependencies
end
end
class ERBTrackerTest < Minitest::Test
def make_tracker(name, template)
ActionView::DependencyTracker::ERBTracker.new(name, template)
end
def test_dependency_of_erb_template_with_number_in_filename
template = FakeTemplate.new("<%# render 'messages/message123' %>", :erb)
tracker = make_tracker("messages/_message123", template)
assert_equal ["messages/message123"], tracker.dependencies
end
def test_finds_dependency_in_correct_directory
template = FakeTemplate.new("<%# render(message.topic) %>", :erb)
tracker = make_tracker("messages/_message", template)
assert_equal ["topics/topic"], tracker.dependencies
end
def test_finds_dependency_in_correct_directory_with_underscore
template = FakeTemplate.new("<%# render(message_type.messages) %>", :erb)
tracker = make_tracker("message_types/_message_type", template)
assert_equal ["messages/message"], tracker.dependencies
end
def test_dependency_of_erb_template_with_no_spaces_after_render
template = FakeTemplate.new("<%# render'messages/message' %>", :erb)
tracker = make_tracker("messages/_message", template)
assert_equal ["messages/message"], tracker.dependencies
end
def test_finds_no_dependency_when_render_begins_the_name_of_an_identifier
template = FakeTemplate.new("<%# rendering 'it useless' %>", :erb)
tracker = make_tracker("resources/_resource", template)
assert_equal [], tracker.dependencies
end
def test_finds_no_dependency_when_render_ends_the_name_of_another_method
template = FakeTemplate.new("<%# surrender 'to reason' %>", :erb)
tracker = make_tracker("resources/_resource", template)
assert_equal [], tracker.dependencies
end
def test_finds_dependency_on_multiline_render_calls
template = FakeTemplate.new("<%#
render :object => @all_posts,
:partial => 'posts' %>", :erb)
tracker = make_tracker("some/_little_posts", template)
assert_equal ["some/posts"], tracker.dependencies
end
def test_finds_multiple_unrelated_odd_dependencies
template = FakeTemplate.new("
<%# render('shared/header', title: 'Title') %>
<h2>Section title</h2>
<%# render@section %>
", :erb)
tracker = make_tracker("multiple/_dependencies", template)
assert_equal ["shared/header", "sections/section"], tracker.dependencies
end
def test_finds_dependencies_for_all_kinds_of_identifiers
template = FakeTemplate.new("
<%# render $globals %>
<%# render @instance_variables %>
<%# render @@class_variables %>
", :erb)
tracker = make_tracker("identifiers/_all", template)
assert_equal [
"globals/global",
"instance_variables/instance_variable",
"class_variables/class_variable"
], tracker.dependencies
end
def test_finds_dependencies_on_method_chains
template = FakeTemplate.new("<%# render @parent.child.grandchildren %>", :erb)
tracker = make_tracker("method/_chains", template)
assert_equal ["grandchildren/grandchild"], tracker.dependencies
end
def test_finds_dependencies_with_special_characters
template = FakeTemplate.new("<%# render @pokémon, partial: 'ピカチュウ' %>", :erb)
tracker = make_tracker("special/_characters", template)
assert_equal ["special/ピカチュウ"], tracker.dependencies
end
def test_finds_dependencies_with_quotes_within
template = FakeTemplate.new("
<%# render \"single/quote's\" %>
<%# render 'double/quote\"s' %>
", :erb)
tracker = make_tracker("quotes/_single_and_double", template)
assert_equal ["single/quote's", 'double/quote"s'], tracker.dependencies
end
end