lib/rubocop/cop/jbuilder/partial_exists.rb in rubocop-jbuilder-0.1.0 vs lib/rubocop/cop/jbuilder/partial_exists.rb in rubocop-jbuilder-0.1.1
- old
+ new
@@ -1,38 +1,58 @@
# frozen_string_literal: true
-TEST_FILENAME = File.join(Dir.pwd, "app/views/testing/show.json.jbuilder")
+require 'pathname'
+TEST_FILENAME = File.join(Dir.pwd, "app/views/testing/nested/show.json.jbuilder")
+
module RuboCop
module Cop
module Jbuilder
class PartialExists < Base
- MSG = "Partial not found. Looked for: %<path>s"
+ MSG = "Partial not found. Looked for: %<paths>s"
def_node_matcher :has_partial?, <<~PATTERN
{
(send (send nil? :json) :partial! $str ...)
(send (send nil? :json) ... (hash (pair (sym :partial) $str) ...))
}
PATTERN
def on_send(node)
has_partial?(node) do |actual|
- full_path = get_view_path_from(actual)
- path = full_path.sub(rails_root_dirname(node) + "/", "")
- add_offense(actual, message: format(MSG, path:)) unless File.exist?(full_path)
+ all_paths = get_view_paths_from(actual)
+
+ return if all_paths.any? { |full_path| File.exist?(full_path) }
+
+ base_path = rails_root_dirname(node)
+ relative_paths = all_paths.map { |full_path| relative_path(full_path, base_path) }
+ add_offense(actual, message: format(MSG, paths: relative_paths.join(", ")))
end
end
private
- def get_view_path_from(node)
+ def get_view_paths_from(node)
partial = node.source[1..-2]
segments = partial.split("/")
segments.last.sub!(/.*/, '_\&.json.jbuilder')
- dirname = (segments.count == 1) ? sut_dirname(node) : rails_views_dirname(node)
- File.join(dirname, *segments)
+ specific_path = segments.count != 1
+ return [File.join(rails_views_dirname(node), *segments)] if specific_path
+
+ paths = []
+ current_dirname = sut_dirname(node)
+ while current_dirname != rails_views_dirname(node)
+ paths << File.join(current_dirname, *segments)
+ current_dirname = File.expand_path("..", current_dirname)
+ end
+ paths
+ end
+
+ def relative_path(full_path, base_path)
+ full = Pathname.new(full_path)
+ base = Pathname.new(base_path)
+ full.relative_path_from(base).to_s
end
def sut_dirname(node)
File.dirname(filename(node))
end