Skip to content

Commit

Permalink
Enforce presence of view component preview files
Browse files Browse the repository at this point in the history
  • Loading branch information
Dany Marcoux committed Feb 23, 2023
1 parent 6732b13 commit 8b3b492
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/api/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ require:
- ./lib/rubocop/cop/view_component/avoid_global_state.rb
- ./lib/rubocop/cop/view_component/file_name.rb
- ./lib/rubocop/cop/view_component/class_name.rb
- ./lib/rubocop/cop/view_component/missing_preview_file.rb

inherit_from: .rubocop_todo.yml

Expand Down
30 changes: 30 additions & 0 deletions src/api/lib/rubocop/cop/view_component/missing_preview_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module RuboCop
module Cop
module ViewComponent
class MissingPreviewFile < RuboCop::Cop::Base
include RuboCop::Cop::RangeHelp # for source_range

def on_new_investigation
super

component_filename = File.basename(processed_source.file_path)

# Only consider Ruby files, anything else is ignored, even Haml templates ending with `.html.haml.rb`
return unless component_filename.end_with?('_component.rb')
# The ApplicationComponent should not have a preview file
return if component_filename == 'application_component.rb'

preview_filename = component_filename.gsub(/\.rb$/, '_preview.rb')
# Relative path from `Rails.root`, but we cannot use that method since it is not available inside a RuboCop cop
preview_file_relative_path = "spec/components/previews/#{preview_filename}"
preview_file = File.join(Dir.pwd, preview_file_relative_path)

return if File.exist?(preview_file)

add_offense(source_range(processed_source.buffer, 1, 0),
message: "This view component should have a preview file (`src/api/#{preview_file_relative_path}`)")
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require 'rails_helper'
require './lib/rubocop/cop/view_component/missing_preview_file'

RSpec.describe RuboCop::Cop::ViewComponent::MissingPreviewFile, :config do
let(:config) do
RuboCop::Config.new({ 'ViewComponent' => { 'Include' => ['app/components/**/*.rb'] } }, '/some/.rubocop.yml')
end

context 'when a view component does not have a preview file' do
it 'registers an offense' do
expect_offense(<<~RUBY, 'app/components/user_component.rb')
class UserComponent < ApplicationComponent
^ This view component should have a preview file (`src/api/spec/components/previews/user_component_preview.rb`)
def initialize
@abc = 'abc'
end
end
RUBY
end
end

context 'when a view component has a preview file' do
before do
allow(File).to receive(:exist?).with(Rails.root.join('spec/components/previews/user_component_preview.rb').to_s).and_return(true)
end

it 'does not register an offense' do
expect_no_offenses(<<~RUBY, 'app/components/user_component.rb')
class UserComponent < ApplicationComponent
def initialize
@abc = 'abc'
end
end
RUBY
end
end

context 'when the ApplicationComponent does not have a preview file' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY, 'app/components/application_component.rb')
class ApplicationComponent
def initialize
@abc = 'abc'
end
end
RUBY
end
end

context 'when a file which is not a view component class' do
it 'does not register an offense' do
expect_no_offenses(<<~HAML, 'app/components/user_component.html.haml.rb')
Hello world!
HAML
end
end
end

0 comments on commit 8b3b492

Please sign in to comment.