rubocop-view_component 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
4
+ let(:config) { RuboCop::Config.new }
5
+
6
+ context "when component has public helper methods" do
7
+ it "registers offense for public helper method" do
8
+ expect_offense(<<~RUBY)
9
+ class CardComponent < ViewComponent::Base
10
+ def initialize(title)
11
+ @title = title
12
+ end
13
+
14
+ def formatted_title
15
+ ^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making this method private. Only ViewComponent interface methods should be public.
16
+ @title.upcase
17
+ end
18
+ end
19
+ RUBY
20
+ end
21
+
22
+ it "registers offense for multiple public helpers" do
23
+ expect_offense(<<~RUBY)
24
+ class CardComponent < ViewComponent::Base
25
+ def helper_one
26
+ ^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making this method private. Only ViewComponent interface methods should be public.
27
+ 'one'
28
+ end
29
+
30
+ def helper_two
31
+ ^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making this method private. Only ViewComponent interface methods should be public.
32
+ 'two'
33
+ end
34
+ end
35
+ RUBY
36
+ end
37
+ end
38
+
39
+ context "when helper methods are already private" do
40
+ it "does not register offense" do
41
+ expect_no_offenses(<<~RUBY)
42
+ class CardComponent < ViewComponent::Base
43
+ def initialize(title)
44
+ @title = title
45
+ end
46
+
47
+ private
48
+
49
+ def formatted_title
50
+ @title.upcase
51
+ end
52
+ end
53
+ RUBY
54
+ end
55
+ end
56
+
57
+ context "with allowed public interface methods" do
58
+ it "allows initialize" do
59
+ expect_no_offenses(<<~RUBY)
60
+ class CardComponent < ViewComponent::Base
61
+ def initialize(title)
62
+ @title = title
63
+ end
64
+ end
65
+ RUBY
66
+ end
67
+
68
+ it "allows call" do
69
+ expect_no_offenses(<<~RUBY)
70
+ class CardComponent < ViewComponent::Base
71
+ def call
72
+ 'rendered'
73
+ end
74
+ end
75
+ RUBY
76
+ end
77
+
78
+ it "allows before_render" do
79
+ expect_no_offenses(<<~RUBY)
80
+ class CardComponent < ViewComponent::Base
81
+ def before_render
82
+ @computed = true
83
+ end
84
+ end
85
+ RUBY
86
+ end
87
+
88
+ it "allows render?" do
89
+ expect_no_offenses(<<~RUBY)
90
+ class CardComponent < ViewComponent::Base
91
+ def render?
92
+ @show
93
+ end
94
+ end
95
+ RUBY
96
+ end
97
+ end
98
+
99
+ context "with mixed visibility" do
100
+ it "only flags public methods" do
101
+ expect_offense(<<~RUBY)
102
+ class CardComponent < ViewComponent::Base
103
+ def public_helper
104
+ ^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making this method private. Only ViewComponent interface methods should be public.
105
+ 'public'
106
+ end
107
+
108
+ private
109
+
110
+ def private_helper
111
+ 'private'
112
+ end
113
+
114
+ public
115
+
116
+ def another_public
117
+ ^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making this method private. Only ViewComponent interface methods should be public.
118
+ 'public'
119
+ end
120
+ end
121
+ RUBY
122
+ end
123
+ end
124
+
125
+ context "when not a ViewComponent" do
126
+ it "does not register offense" do
127
+ expect_no_offenses(<<~RUBY)
128
+ class RegularClass
129
+ def public_method
130
+ 'public'
131
+ end
132
+ end
133
+ RUBY
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe RuboCop::Cop::ViewComponent::PreferSlots, :config do
4
+ let(:config) { RuboCop::Config.new }
5
+
6
+ context "when initialize has HTML parameter names" do
7
+ it "registers offense for _html suffix" do
8
+ expect_offense(<<~RUBY)
9
+ class ModalComponent < ViewComponent::Base
10
+ def initialize(title:, body_html:)
11
+ ^^^^^^^^^^ ViewComponent/PreferSlots: Consider using `renders_one :body` instead of passing HTML as a parameter. This maintains Rails' automatic HTML escaping.
12
+ @title = title
13
+ @body_html = body_html
14
+ end
15
+ end
16
+ RUBY
17
+ end
18
+
19
+ it "registers offense for _content suffix" do
20
+ expect_offense(<<~RUBY)
21
+ class ModalComponent < ViewComponent::Base
22
+ def initialize(title:, body_content:)
23
+ ^^^^^^^^^^^^^ ViewComponent/PreferSlots: Consider using `renders_one :body` instead of passing HTML as a parameter. This maintains Rails' automatic HTML escaping.
24
+ @title = title
25
+ @body_content = body_content
26
+ end
27
+ end
28
+ RUBY
29
+ end
30
+
31
+ it "registers offense for html_ prefix" do
32
+ expect_offense(<<~RUBY)
33
+ class ModalComponent < ViewComponent::Base
34
+ def initialize(title:, html_body:)
35
+ ^^^^^^^^^^ ViewComponent/PreferSlots: Consider using `renders_one :body` instead of passing HTML as a parameter. This maintains Rails' automatic HTML escaping.
36
+ @title = title
37
+ @html_body = html_body
38
+ end
39
+ end
40
+ RUBY
41
+ end
42
+
43
+ it "registers offense for content parameter" do
44
+ expect_offense(<<~RUBY)
45
+ class ModalComponent < ViewComponent::Base
46
+ def initialize(title:, content:)
47
+ ^^^^^^^^ ViewComponent/PreferSlots: Consider using `renders_one :content` instead of passing HTML as a parameter. This maintains Rails' automatic HTML escaping.
48
+ @title = title
49
+ @content = content
50
+ end
51
+ end
52
+ RUBY
53
+ end
54
+ end
55
+
56
+ context "when parameter has html_safe default value" do
57
+ it "registers offense" do
58
+ expect_offense(<<~RUBY)
59
+ class ModalComponent < ViewComponent::Base
60
+ def initialize(title:, body: "".html_safe)
61
+ ^^^^^^^^^^^^^^^^^^ ViewComponent/PreferSlots: Consider using `renders_one :body` instead of passing HTML as a parameter. This maintains Rails' automatic HTML escaping.
62
+ @title = title
63
+ @body = body
64
+ end
65
+ end
66
+ RUBY
67
+ end
68
+ end
69
+
70
+ context "when parameters are not HTML-related" do
71
+ it "does not register offense for regular parameters" do
72
+ expect_no_offenses(<<~RUBY)
73
+ class CardComponent < ViewComponent::Base
74
+ def initialize(title:, description:)
75
+ @title = title
76
+ @description = description
77
+ end
78
+ end
79
+ RUBY
80
+ end
81
+
82
+ it "does not register offense for html_class" do
83
+ expect_no_offenses(<<~RUBY)
84
+ class CardComponent < ViewComponent::Base
85
+ def initialize(title:, html_class:)
86
+ @title = title
87
+ @html_class = html_class
88
+ end
89
+ end
90
+ RUBY
91
+ end
92
+ end
93
+
94
+ context "when not a ViewComponent" do
95
+ it "does not register offense" do
96
+ expect_no_offenses(<<~RUBY)
97
+ class RegularClass
98
+ def initialize(body_html:)
99
+ @body_html = body_html
100
+ end
101
+ end
102
+ RUBY
103
+ end
104
+ end
105
+
106
+ context "when component uses slots" do
107
+ it "does not register offense" do
108
+ expect_no_offenses(<<~RUBY)
109
+ class ModalComponent < ViewComponent::Base
110
+ renders_one :body
111
+
112
+ def initialize(title:)
113
+ @title = title
114
+ end
115
+ end
116
+ RUBY
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop-view_component"
4
+ require "rubocop/rspec/support"
5
+
6
+ RSpec.configure do |config|
7
+ config.disable_monkey_patching!
8
+ config.raise_errors_for_deprecations!
9
+ config.raise_on_warning = true
10
+ config.fail_if_no_examples = true
11
+
12
+ config.order = :random
13
+ Kernel.srand config.seed
14
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubocop-view_component
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andy Waite
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: lint_roller
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.1'
26
+ - !ruby/object:Gem::Dependency
27
+ name: parser
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rubocop
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.72.2
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.72.2
54
+ description: A RuboCop extension that enforces ViewComponent best practices and conventions
55
+ email:
56
+ - andyw8@users.noreply.github.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".rspec"
62
+ - ".rubocop.yml"
63
+ - IMPLEMENTATION_SUMMARY.md
64
+ - LICENSE.txt
65
+ - PLAN.md
66
+ - README.md
67
+ - Rakefile
68
+ - config/default.yml
69
+ - lib/rubocop-view_component.rb
70
+ - lib/rubocop/cop/view_component/base.rb
71
+ - lib/rubocop/cop/view_component/component_suffix.rb
72
+ - lib/rubocop/cop/view_component/no_global_state.rb
73
+ - lib/rubocop/cop/view_component/prefer_private_methods.rb
74
+ - lib/rubocop/cop/view_component/prefer_slots.rb
75
+ - lib/rubocop/cop/view_component_cops.rb
76
+ - lib/rubocop/view_component.rb
77
+ - lib/rubocop/view_component/plugin.rb
78
+ - lib/rubocop/view_component/version.rb
79
+ - spec/rubocop/cop/view_component/component_suffix_spec.rb
80
+ - spec/rubocop/cop/view_component/no_global_state_spec.rb
81
+ - spec/rubocop/cop/view_component/prefer_private_methods_spec.rb
82
+ - spec/rubocop/cop/view_component/prefer_slots_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage: https://github.com/andyw8/rubocop-view_component
85
+ licenses:
86
+ - MIT
87
+ metadata:
88
+ homepage_uri: https://github.com/andyw8/rubocop-view_component
89
+ source_code_uri: https://github.com/andyw8/rubocop-view_component
90
+ default_lint_roller_plugin: RuboCop::ViewComponent::Plugin
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 2.7.0
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubygems_version: 3.6.9
106
+ specification_version: 4
107
+ summary: RuboCop extension for ViewComponent best practices
108
+ test_files: []