Skip to content

Commit 8e73cea

Browse files
committed
Track template dependencies
closes #126
1 parent ef14a68 commit 8e73cea

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

lib/jbuilder/dependency_tracker.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
require 'jbuilder'
2+
require 'action_view'
3+
require 'action_view/dependency_tracker'
4+
5+
class Jbuilder
6+
class DependencyTracker < ::ActionView::DependencyTracker::ERBTracker
7+
# Matches:
8+
# json.partial! "messages/message"
9+
DIRECT_RENDERS = /
10+
\w+\.partial! # json.partial!
11+
\(?\s* # optional parenthesis
12+
(['"])([^""]+)\1 # quoted value
13+
/x
14+
15+
16+
# Matches:
17+
# json.partial! partial: "comments/comment"
18+
# json.comments @post.comments, partial: "comments/comment", as: :comment
19+
# json.array! @posts, partial: "posts/post", as: :post
20+
# = render partial: "account"
21+
#
22+
INDIRECT_RENDERS = /
23+
(?::partial\s*=>|partial:)
24+
\s*
25+
(['"])([^'"]+)\1
26+
/x
27+
28+
def dependencies
29+
direct_dependencies + indirect_dependencies + explicit_dependencies
30+
end
31+
32+
def direct_dependencies
33+
source.scan(DIRECT_RENDERS).map(&:second)
34+
end
35+
36+
def indirect_dependencies
37+
source.scan(INDIRECT_RENDERS).map(&:second)
38+
end
39+
end
40+
end
41+
42+
43+
ActiveSupport.on_load :action_view do
44+
ActiveSupport.on_load :after_initialize do
45+
ActionView::DependencyTracker.register_tracker :jbuilder, Jbuilder::DependencyTracker
46+
end
47+
end
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
require 'test/unit'
2+
require 'active_support/test_case'
3+
require 'jbuilder/dependency_tracker'
4+
5+
6+
class FakeTemplate
7+
attr_reader :source, :handler
8+
def initialize(source, handler = :jbuilder)
9+
@source, @handler = source, handler
10+
end
11+
end
12+
13+
14+
class JbuilderDependencyTrackerTest < ActiveSupport::TestCase
15+
def make_tracker(name, source)
16+
template = FakeTemplate.new(source)
17+
Jbuilder::DependencyTracker.new(name, template)
18+
end
19+
20+
def track_dependencies(source)
21+
make_tracker('jbuilder_template', source).dependencies
22+
end
23+
24+
test 'detects dependency via direct partial! call' do
25+
dependencies = track_dependencies <<-RUBY
26+
json.partial! 'path/to/partial'
27+
RUBY
28+
29+
assert_equal %w[path/to/partial], dependencies
30+
end
31+
32+
test 'detects dependency via direct partial! call with parens' do
33+
dependencies = track_dependencies <<-RUBY
34+
json.partial!("path/to/partial")
35+
RUBY
36+
37+
assert_equal %w[path/to/partial], dependencies
38+
end
39+
40+
test 'detects partial with options (1.9 style)' do
41+
dependencies = track_dependencies <<-RUBY
42+
json.partial! hello: 'world', partial: 'path/to/partial', foo: :bar
43+
RUBY
44+
45+
assert_equal %w[path/to/partial], dependencies
46+
end
47+
48+
test 'detects partial with options (1.8 style)' do
49+
dependencies = track_dependencies <<-RUBY
50+
json.partial! :hello => 'world', :partial => 'path/to/partial', :foo => :bar
51+
RUBY
52+
53+
assert_equal %w[path/to/partial], dependencies
54+
end
55+
56+
test 'detects partial in indirect collecton calls' do
57+
dependencies = track_dependencies <<-RUBY
58+
json.comments @post.comments, partial: 'comments/comment', as: :comment
59+
RUBY
60+
61+
assert_equal %w[comments/comment], dependencies
62+
end
63+
end

0 commit comments

Comments
 (0)