Skip to content

Commit 7205a35

Browse files
committed
Delegate properly to custom Resolver instances
Let `EmptyTemplateResolver` creating instances of either `EmptyTemplateResolver::ResolverDecorator` or `EmptyTemplateResolver::FileSystemResolver`, depending on whether the given path is an `ActionView::Resolver` instance or not. The new `EmptyTemplateResolver::ResolverDecorator` class simply delegates all method calls to its given resolver, checks the return values, and changes collections of `ActionView::Template` instances into templates that render with `EmptyTemplateHandler`. The alternative was to implement both `#find_all` and `#find_all_anywhere`. The latter is only present since Rails 4.2.5.1, and the former has different arity in different Rails versions.
1 parent 7bc5230 commit 7205a35

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

lib/rspec/rails/view_rendering.rb

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,18 @@ def render_views?
3939
self.class.render_views? || !controller.class.respond_to?(:view_paths)
4040
end
4141

42-
# Delegates find_all to the submitted path set and then returns templates
43-
# with modified source
44-
#
4542
# @private
46-
class EmptyTemplateResolver < ::ActionView::FileSystemResolver
47-
private
43+
class EmptyTemplateResolver
44+
def self.build(path)
45+
if path.is_a?(::ActionView::Resolver)
46+
ResolverDecorator.new(path)
47+
else
48+
FileSystemResolver.new(path)
49+
end
50+
end
4851

49-
def find_templates(*args)
50-
super.map do |template|
52+
def self.nullify_template_rendering(templates)
53+
templates.map do |template|
5154
::ActionView::Template.new(
5255
"",
5356
template.identifier,
@@ -57,6 +60,44 @@ def find_templates(*args)
5760
)
5861
end
5962
end
63+
64+
# Delegates all methods to the submitted resolver and for all methods
65+
# that return a collection of `ActionView::Template` instances, return
66+
# templates with modified source
67+
#
68+
# @private
69+
class ResolverDecorator
70+
def initialize(resolver)
71+
@resolver = resolver
72+
end
73+
74+
def method_missing(name, *args, &block)
75+
result = @resolver.send(name, *args, &block)
76+
nullify_templates(result)
77+
end
78+
79+
private
80+
81+
def nullify_templates(collection)
82+
return collection unless collection.is_a?(Enumerable)
83+
return collection unless collection.all? { |element| element.is_a?(::ActionView::Template) }
84+
85+
EmptyTemplateResolver.nullify_template_rendering(collection)
86+
end
87+
end
88+
89+
# Delegates find_templates to the submitted path set and then returns
90+
# templates with modified source
91+
#
92+
# @private
93+
class FileSystemResolver < ::ActionView::FileSystemResolver
94+
private
95+
96+
def find_templates(*args)
97+
templates = super
98+
EmptyTemplateResolver.nullify_template_rendering(templates)
99+
end
100+
end
60101
end
61102

62103
# @private
@@ -81,13 +122,13 @@ def append_view_path(new_path)
81122
private
82123

83124
def _path_decorator(*paths)
84-
paths.map { |path| EmptyTemplateResolver.new(path) }
125+
paths.map { |path| EmptyTemplateResolver.build(path) }
85126
end
86127
end
87128

88129
# @private
89130
RESOLVER_CACHE = Hash.new do |hash, path|
90-
hash[path] = EmptyTemplateResolver.new(path)
131+
hash[path] = EmptyTemplateResolver.build(path)
91132
end
92133

93134
included do

spec/rspec/rails/view_rendering_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ def example.controller
139139
expect(controller.view_paths.map(&:to_s)).to match_paths 'app/views', 'app/legacy_views', 'app/others', 'app/more_views'
140140
end
141141

142+
it 'supports manipulating view paths with resolvers' do
143+
expect {
144+
controller.prepend_view_path ActionView::Resolver.new
145+
controller.append_view_path ActionView::Resolver.new
146+
}.to_not raise_error
147+
end
148+
142149
def match_paths(*paths)
143150
eq paths.map { |path| File.expand_path path }
144151
end

0 commit comments

Comments
 (0)