Sha256: f62b4c819145aa6a28cf8edbf61f5216db4f2f21f19bd4d394d4a054e79a672e

Contents?: true

Size: 1.56 KB

Versions: 1

Compression:

Stored size: 1.56 KB

Contents

# frozen_string_literal: true

TEST_FILENAME = File.join(Dir.pwd, "app/views/testing/show.json.jbuilder")

module RuboCop
  module Cop
    module Jbuilder
      class PartialExists < Base
        MSG = "Partial not found. Looked for: %<path>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)
          end
        end

        private

        def get_view_path_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)
        end

        def sut_dirname(node)
          File.dirname(filename(node))
        end

        def rails_views_dirname(node)
          File.join(rails_root_dirname(node), "app/views")
        end

        def rails_root_dirname(node)
          filename(node).split("/app/").first
        end

        def filename(node)
          filename = node.location.expression.source_buffer.name

          (filename == "(string)") ? TEST_FILENAME : filename
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rubocop-jbuilder-0.1.0 lib/rubocop/cop/jbuilder/partial_exists.rb