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