rubocop-view_component 0.2.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CLAUDE.md +72 -0
- data/README.md +71 -23
- data/config/default.yml +18 -0
- data/lib/rubocop/cop/view_component/prefer_composition.rb +44 -0
- data/lib/rubocop/cop/view_component/prefer_private_methods.rb +2 -2
- data/lib/rubocop/cop/view_component/prefer_slots.rb +3 -23
- data/lib/rubocop/cop/view_component/test_rendered_output.rb +82 -0
- data/lib/rubocop/cop/view_component_cops.rb +2 -0
- data/lib/rubocop/view_component/version.rb +1 -1
- data/script/verify +197 -0
- data/spec/expected_govuk_failures.yml +39 -0
- data/spec/expected_polaris_failures.yml +65 -0
- data/spec/expected_primer_failures.yml +27 -0
- data/spec/rubocop/cop/view_component/prefer_composition_spec.rb +83 -0
- data/spec/rubocop/cop/view_component/prefer_private_methods_spec.rb +8 -8
- data/spec/rubocop/cop/view_component/prefer_slots_spec.rb +24 -38
- data/spec/rubocop/cop/view_component/test_rendered_output_spec.rb +168 -0
- data/verification/govuk_rubocop_config.yml +3 -0
- data/verification/libraries.yml +11 -0
- data/verification/polaris_rubocop_config.yml +4 -0
- data/verification/primer_rubocop_config.yml +24 -0
- metadata +14 -6
- data/IMPLEMENTATION_PLAN.md +0 -177
- data/IMPLEMENTATION_SUMMARY.md +0 -172
- data/PLAN.md +0 -625
- data/script/verify_against_primer.rb +0 -128
- data/spec/expected_primer_failures.json +0 -818
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# This file is auto-generated by `script/verify --regenerate`.
|
|
2
|
+
# It captures known offenses in the library source.
|
|
3
|
+
---
|
|
4
|
+
ViewComponent/ComponentSuffix:
|
|
5
|
+
- app/components/govuk_component/base.rb:1 # ViewComponent class names should end with `Component`. (https://viewcomponent.org/best_practices.html)
|
|
6
|
+
- app/components/govuk_component/header_component.rb:46 # ViewComponent class names should end with `Component`. (https://viewcomponent.org/best_practices.html)
|
|
7
|
+
- app/components/govuk_component/notification_banner_component.rb:33 # ViewComponent class names should end with `Component`. (https://viewcomponent.org/best_practices.html)
|
|
8
|
+
- app/components/govuk_component/pagination_component/adjacent_page.rb:1 # ViewComponent class names should end with `Component`. (https://viewcomponent.org/best_practices.html)
|
|
9
|
+
- app/components/govuk_component/pagination_component/item.rb:1 # ViewComponent class names should end with `Component`. (https://viewcomponent.org/best_practices.html)
|
|
10
|
+
- app/components/govuk_component/tab_component.rb:21 # ViewComponent class names should end with `Component`. (https://viewcomponent.org/best_practices.html)
|
|
11
|
+
ViewComponent/PreferPrivateMethods:
|
|
12
|
+
- app/components/govuk_component/base.rb:29 # Consider making `brand` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
13
|
+
- app/components/govuk_component/base.rb:35 # Consider making `class_prefix` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
14
|
+
- app/components/govuk_component/notification_banner_component.rb:55 # Consider making `link` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
15
|
+
- app/components/govuk_component/notification_banner_component.rb:59 # Consider making `default_attributes` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
16
|
+
- app/components/govuk_component/service_navigation_component.rb:54 # Consider making `navigation` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
17
|
+
- app/components/govuk_component/service_navigation_component.rb:62 # Consider making `navigation_list` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
18
|
+
- app/components/govuk_component/tab_component.rb:32 # Consider making `hidden_class` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
19
|
+
- app/components/govuk_component/tab_component.rb:38 # Consider making `li_classes` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
20
|
+
- app/components/govuk_component/tab_component.rb:42 # Consider making `li_link` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
21
|
+
- app/components/govuk_component/tab_component.rb:46 # Consider making `default_attributes` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
22
|
+
- app/components/govuk_component/tab_component.rb:50 # Consider making `combined_attributes` private. Only ViewComponent interface methods should be public. (https://viewcomponent.org/best_practices.html)
|
|
23
|
+
ViewComponent/TestRenderedOutput:
|
|
24
|
+
- spec/components/govuk_component/accordion_component_spec.rb:84 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
25
|
+
- spec/components/govuk_component/breadcrumbs_component_spec.rb:44 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
26
|
+
- spec/components/govuk_component/configuration/footer_component_configuration_spec.rb:42 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
27
|
+
- spec/components/govuk_component/footer_component_spec.rb:123 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
28
|
+
- spec/components/govuk_component/footer_component_spec.rb:182 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
29
|
+
- spec/components/govuk_component/footer_component_spec.rb:235 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
30
|
+
- spec/components/govuk_component/footer_component_spec.rb:254 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
31
|
+
- spec/components/govuk_component/footer_component_spec.rb:274 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
32
|
+
- spec/components/govuk_component/footer_component_spec.rb:294 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
33
|
+
- spec/components/govuk_component/footer_component_spec.rb:312 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
34
|
+
- spec/components/govuk_component/footer_component_spec.rb:336 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
35
|
+
- spec/components/govuk_component/notification_banner_component_spec.rb:59 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
36
|
+
- spec/components/govuk_component/pagination_component_spec.rb:317 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
37
|
+
- spec/components/govuk_component/task_list_component_spec.rb:139 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
38
|
+
- spec/components/govuk_component/warning_text_component_spec.rb:11 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
39
|
+
- spec/components/govuk_component/warning_text_component_spec.rb:41 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly. (https://viewcomponent.org/guide/testing.html)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# This file is auto-generated by `script/verify --regenerate`.
|
|
2
|
+
# It captures known offenses in the library source.
|
|
3
|
+
---
|
|
4
|
+
ViewComponent/ComponentSuffix:
|
|
5
|
+
- app/components/polaris/base_button.rb:4 # ViewComponent class names should end with `Component`.
|
|
6
|
+
- app/components/polaris/base_checkbox.rb:2 # ViewComponent class names should end with `Component`.
|
|
7
|
+
- app/components/polaris/base_radio_button.rb:2 # ViewComponent class names should end with `Component`.
|
|
8
|
+
- app/components/polaris/headless_button.rb:4 # ViewComponent class names should end with `Component`.
|
|
9
|
+
- app/components/polaris/layout/annotated_section.rb:5 # ViewComponent class names should end with `Component`.
|
|
10
|
+
- app/components/polaris/layout/section.rb:5 # ViewComponent class names should end with `Component`.
|
|
11
|
+
- app/components/polaris/text_field_component.rb:195 # ViewComponent class names should end with `Component`.
|
|
12
|
+
ViewComponent/NoGlobalState:
|
|
13
|
+
- app/components/polaris/shopify_navigation_component.rb:59 # Avoid accessing `request` directly in ViewComponents. Pass necessary data through the constructor instead.
|
|
14
|
+
ViewComponent/PreferPrivateMethods:
|
|
15
|
+
- app/components/polaris/action_list/section_component.rb:16 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
16
|
+
- app/components/polaris/avatar_component.rb:43 # Consider making `style_class` private. Only ViewComponent interface methods should be public.
|
|
17
|
+
- app/components/polaris/avatar_component.rb:69 # Consider making `xor_hash` private. Only ViewComponent interface methods should be public.
|
|
18
|
+
- app/components/polaris/banner_component.rb:77 # Consider making `default_icon` private. Only ViewComponent interface methods should be public.
|
|
19
|
+
- app/components/polaris/base_checkbox.rb:24 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
20
|
+
- app/components/polaris/base_checkbox.rb:40 # Consider making `indeterminate?` private. Only ViewComponent interface methods should be public.
|
|
21
|
+
- app/components/polaris/base_radio_button.rb:21 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
22
|
+
- app/components/polaris/button_group_component.rb:60 # Consider making `all_items` private. Only ViewComponent interface methods should be public.
|
|
23
|
+
- app/components/polaris/checkbox_component.rb:62 # Consider making `indeterminate?` private. Only ViewComponent interface methods should be public.
|
|
24
|
+
- app/components/polaris/choice_list_component.rb:58 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
25
|
+
- app/components/polaris/choice_list_component.rb:62 # Consider making `multiple_choice_allowed?` private. Only ViewComponent interface methods should be public.
|
|
26
|
+
- app/components/polaris/collapsible_component.rb:15 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
27
|
+
- app/components/polaris/description_list_component.rb:24 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
28
|
+
- app/components/polaris/dropzone_component.rb:142 # Consider making `drop_actions` private. Only ViewComponent interface methods should be public.
|
|
29
|
+
- app/components/polaris/exception_list_component.rb:16 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
30
|
+
- app/components/polaris/filters_component.rb:74 # Consider making `popover_arguments` private. Only ViewComponent interface methods should be public.
|
|
31
|
+
- app/components/polaris/form_layout_component.rb:29 # Consider making `all_items` private. Only ViewComponent interface methods should be public.
|
|
32
|
+
- app/components/polaris/headless_button.rb:104 # Consider making `html_options` private. Only ViewComponent interface methods should be public.
|
|
33
|
+
- app/components/polaris/headless_button.rb:96 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
34
|
+
- app/components/polaris/index_table/cell_component.rb:7 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
35
|
+
- app/components/polaris/inline_error_component.rb:14 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
36
|
+
- app/components/polaris/keyboard_key_component.rb:9 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
37
|
+
- app/components/polaris/label_component.rb:32 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
38
|
+
- app/components/polaris/layout_component.rb:38 # Consider making `all_sections` private. Only ViewComponent interface methods should be public.
|
|
39
|
+
- app/components/polaris/modal/section_component.rb:6 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
40
|
+
- app/components/polaris/navigation/item_component.rb:54 # Consider making `item_inner_wrapper_classes` private. Only ViewComponent interface methods should be public.
|
|
41
|
+
- app/components/polaris/navigation/item_component.rb:62 # Consider making `link_classes` private. Only ViewComponent interface methods should be public.
|
|
42
|
+
- app/components/polaris/navigation/item_component.rb:71 # Consider making `selected_sub_items?` private. Only ViewComponent interface methods should be public.
|
|
43
|
+
- app/components/polaris/navigation_component.rb:11 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
44
|
+
- app/components/polaris/navigation_list_component.rb:9 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
45
|
+
- app/components/polaris/new_tabs_component.rb:33 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
46
|
+
- app/components/polaris/option_list/checkbox_component.rb:25 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
47
|
+
- app/components/polaris/option_list/option_component.rb:6 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
48
|
+
- app/components/polaris/option_list/radio_button_component.rb:32 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
49
|
+
- app/components/polaris/option_list/section_component.rb:42 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
50
|
+
- app/components/polaris/page_component.rb:57 # Consider making `title_length` private. Only ViewComponent interface methods should be public.
|
|
51
|
+
- app/components/polaris/popover/section_component.rb:6 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
52
|
+
- app/components/polaris/popover_component.rb:112 # Consider making `popover_placement` private. Only ViewComponent interface methods should be public.
|
|
53
|
+
- app/components/polaris/resource_item/shortcut_actions_component.rb:82 # Consider making `action_list_item_arguments` private. Only ViewComponent interface methods should be public.
|
|
54
|
+
- app/components/polaris/resource_list_component.rb:37 # Consider making `resource_string` private. Only ViewComponent interface methods should be public.
|
|
55
|
+
- app/components/polaris/resource_list_component.rb:43 # Consider making `count` private. Only ViewComponent interface methods should be public.
|
|
56
|
+
- app/components/polaris/select_component.rb:88 # Consider making `hides_label?` private. Only ViewComponent interface methods should be public.
|
|
57
|
+
- app/components/polaris/shopify_navigation_component.rb:40 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
58
|
+
- app/components/polaris/shopify_navigation_component.rb:56 # Consider making `detect_active` private. Only ViewComponent interface methods should be public.
|
|
59
|
+
- app/components/polaris/skeleton_display_text_component.rb:17 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
60
|
+
- app/components/polaris/skeleton_thumbnail_component.rb:16 # Consider making `system_arguments` private. Only ViewComponent interface methods should be public.
|
|
61
|
+
- app/components/polaris/tabs_component.rb:33 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
62
|
+
- app/components/polaris/text_component.rb:114 # Consider making `alignment_class` private. Only ViewComponent interface methods should be public.
|
|
63
|
+
- app/components/polaris/text_component.rb:120 # Consider making `color_class` private. Only ViewComponent interface methods should be public.
|
|
64
|
+
- app/components/polaris/text_component.rb:126 # Consider making `font_weight_class` private. Only ViewComponent interface methods should be public.
|
|
65
|
+
- app/components/polaris/thumbnail_component.rb:39 # Consider making `renders?` private. Only ViewComponent interface methods should be public.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# This file is auto-generated by `script/verify --regenerate`.
|
|
2
|
+
# It captures known offenses in the library source.
|
|
3
|
+
---
|
|
4
|
+
ViewComponent/PreferPrivateMethods:
|
|
5
|
+
- app/components/primer/alpha/action_list.rb:189 # Consider making `build_item` private. Only ViewComponent interface methods should be public.
|
|
6
|
+
- app/components/primer/alpha/action_list.rb:217 # Consider making `build_avatar_item` private. Only ViewComponent interface methods should be public.
|
|
7
|
+
- app/components/primer/alpha/action_list.rb:228 # Consider making `single_select?` private. Only ViewComponent interface methods should be public.
|
|
8
|
+
- app/components/primer/alpha/action_list.rb:236 # Consider making `allows_selection?` private. Only ViewComponent interface methods should be public.
|
|
9
|
+
- app/components/primer/alpha/action_list.rb:240 # Consider making `acts_as_listbox?` private. Only ViewComponent interface methods should be public.
|
|
10
|
+
- app/components/primer/alpha/action_list.rb:244 # Consider making `acts_as_menu?` private. Only ViewComponent interface methods should be public.
|
|
11
|
+
- app/components/primer/alpha/action_list.rb:248 # Consider making `required_form_arguments_given?` private. Only ViewComponent interface methods should be public.
|
|
12
|
+
- app/components/primer/alpha/action_list.rb:257 # Consider making `will_add_item` private. Only ViewComponent interface methods should be public.
|
|
13
|
+
- app/components/primer/alpha/action_list.rb:53 # Consider making `custom_element_name` private. Only ViewComponent interface methods should be public.
|
|
14
|
+
- app/components/primer/alpha/action_list/divider.rb:33 # Consider making `active?` private. Only ViewComponent interface methods should be public.
|
|
15
|
+
- app/components/primer/alpha/action_list/form_wrapper.rb:53 # Consider making `get?` private. Only ViewComponent interface methods should be public.
|
|
16
|
+
- app/components/primer/alpha/dropdown/menu.rb:96 # Consider making `divider?` private. Only ViewComponent interface methods should be public.
|
|
17
|
+
- app/components/primer/alpha/form_control.rb:101 # Consider making `visually_hide_label?` private. Only ViewComponent interface methods should be public.
|
|
18
|
+
- app/components/primer/alpha/form_control.rb:107 # Consider making `full_width?` private. Only ViewComponent interface methods should be public.
|
|
19
|
+
- app/components/primer/alpha/toggle_switch.rb:94 # Consider making `on?` private. Only ViewComponent interface methods should be public.
|
|
20
|
+
- app/components/primer/alpha/toggle_switch.rb:98 # Consider making `enabled?` private. Only ViewComponent interface methods should be public.
|
|
21
|
+
- app/components/primer/alpha/tree_view/node.rb:155 # Consider making `merge_system_arguments!` private. Only ViewComponent interface methods should be public.
|
|
22
|
+
- app/components/primer/beta/avatar.rb:22 # Consider making `link?` private. Only ViewComponent interface methods should be public.
|
|
23
|
+
- app/components/primer/beta/nav_list.rb:116 # Consider making `build_item` private. Only ViewComponent interface methods should be public.
|
|
24
|
+
- app/components/primer/beta/nav_list.rb:139 # Consider making `build_avatar_item` private. Only ViewComponent interface methods should be public.
|
|
25
|
+
ViewComponent/TestRenderedOutput:
|
|
26
|
+
- test/components/alpha/action_list_test.rb:253 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
27
|
+
- test/components/alpha/action_list_test.rb:268 # Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe RuboCop::Cop::ViewComponent::PreferComposition, :config do
|
|
4
|
+
let(:config) { RuboCop::Config.new }
|
|
5
|
+
|
|
6
|
+
context "when inheriting from another component" do
|
|
7
|
+
it "registers an offense" do
|
|
8
|
+
expect_offense(<<~RUBY)
|
|
9
|
+
class UserCard < BaseCardComponent
|
|
10
|
+
^^^^^^^^^^^^^^^^^ ViewComponent/PreferComposition: Avoid inheriting from another ViewComponent.
|
|
11
|
+
end
|
|
12
|
+
RUBY
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "registers an offense for namespaced component parent" do
|
|
16
|
+
expect_offense(<<~RUBY)
|
|
17
|
+
class UserCard < Admin::CardComponent
|
|
18
|
+
^^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferComposition: Avoid inheriting from another ViewComponent.
|
|
19
|
+
end
|
|
20
|
+
RUBY
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context "when inheriting from ViewComponent::Base" do
|
|
25
|
+
it "does not register an offense" do
|
|
26
|
+
expect_no_offenses(<<~RUBY)
|
|
27
|
+
class UserCardComponent < ViewComponent::Base
|
|
28
|
+
end
|
|
29
|
+
RUBY
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when inheriting from ApplicationComponent" do
|
|
34
|
+
it "does not register an offense" do
|
|
35
|
+
expect_no_offenses(<<~RUBY)
|
|
36
|
+
class UserCardComponent < ApplicationComponent
|
|
37
|
+
end
|
|
38
|
+
RUBY
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when inheriting from a non-component class" do
|
|
43
|
+
it "does not register an offense" do
|
|
44
|
+
expect_no_offenses(<<~RUBY)
|
|
45
|
+
class UserCard < ActiveRecord::Base
|
|
46
|
+
end
|
|
47
|
+
RUBY
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "does not register an offense for plain classes" do
|
|
51
|
+
expect_no_offenses(<<~RUBY)
|
|
52
|
+
class UserCard < SomeOtherBase
|
|
53
|
+
end
|
|
54
|
+
RUBY
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when class has no parent" do
|
|
59
|
+
it "does not register an offense" do
|
|
60
|
+
expect_no_offenses(<<~RUBY)
|
|
61
|
+
class UserCard
|
|
62
|
+
end
|
|
63
|
+
RUBY
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "when ViewComponentParentClasses is configured" do
|
|
68
|
+
let(:config) do
|
|
69
|
+
RuboCop::Config.new(
|
|
70
|
+
"AllCops" => {
|
|
71
|
+
"ViewComponentParentClasses" => ["Primer::Component"]
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "does not register an offense for configured parent classes" do
|
|
77
|
+
expect_no_offenses(<<~RUBY)
|
|
78
|
+
class FooBarComponent < Primer::Component
|
|
79
|
+
end
|
|
80
|
+
RUBY
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -12,7 +12,7 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def formatted_title
|
|
15
|
-
^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
15
|
+
^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `formatted_title` private. Only ViewComponent interface methods should be public.
|
|
16
16
|
@title.upcase
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -23,12 +23,12 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
23
23
|
expect_offense(<<~RUBY)
|
|
24
24
|
class CardComponent < ViewComponent::Base
|
|
25
25
|
def helper_one
|
|
26
|
-
^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
26
|
+
^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `helper_one` private. Only ViewComponent interface methods should be public.
|
|
27
27
|
'one'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def helper_two
|
|
31
|
-
^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
31
|
+
^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `helper_two` private. Only ViewComponent interface methods should be public.
|
|
32
32
|
'two'
|
|
33
33
|
end
|
|
34
34
|
end
|
|
@@ -174,7 +174,7 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
def formatted_title
|
|
177
|
-
^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
177
|
+
^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `formatted_title` private. Only ViewComponent interface methods should be public.
|
|
178
178
|
@title.upcase
|
|
179
179
|
end
|
|
180
180
|
end
|
|
@@ -212,7 +212,7 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
def other_method
|
|
215
|
-
^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
215
|
+
^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `other_method` private. Only ViewComponent interface methods should be public.
|
|
216
216
|
'other'
|
|
217
217
|
end
|
|
218
218
|
end
|
|
@@ -225,7 +225,7 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
225
225
|
expect_offense(<<~RUBY)
|
|
226
226
|
class CardComponent < ViewComponent::Base
|
|
227
227
|
def public_helper
|
|
228
|
-
^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
228
|
+
^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `public_helper` private. Only ViewComponent interface methods should be public.
|
|
229
229
|
'public'
|
|
230
230
|
end
|
|
231
231
|
|
|
@@ -238,7 +238,7 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
238
238
|
public
|
|
239
239
|
|
|
240
240
|
def another_public
|
|
241
|
-
^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
241
|
+
^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `another_public` private. Only ViewComponent interface methods should be public.
|
|
242
242
|
'public'
|
|
243
243
|
end
|
|
244
244
|
end
|
|
@@ -275,7 +275,7 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferPrivateMethods, :config do
|
|
|
275
275
|
end
|
|
276
276
|
|
|
277
277
|
def helper_not_used
|
|
278
|
-
^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making
|
|
278
|
+
^^^^^^^^^^^^^^^^^^^ ViewComponent/PreferPrivateMethods: Consider making `helper_not_used` private. Only ViewComponent interface methods should be public.
|
|
279
279
|
"not used"
|
|
280
280
|
end
|
|
281
281
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
RSpec.describe RuboCop::Cop::ViewComponent::PreferSlots, :config do
|
|
4
4
|
let(:config) { RuboCop::Config.new }
|
|
5
5
|
|
|
6
|
-
context "when initialize has
|
|
6
|
+
context "when initialize has _html parameter suffix" do
|
|
7
7
|
it "registers offense for _html suffix" do
|
|
8
8
|
expect_offense(<<~RUBY)
|
|
9
9
|
class ModalComponent < ViewComponent::Base
|
|
@@ -15,42 +15,6 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferSlots, :config do
|
|
|
15
15
|
end
|
|
16
16
|
RUBY
|
|
17
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
18
|
end
|
|
55
19
|
|
|
56
20
|
context "when parameter has html_safe default value" do
|
|
@@ -79,7 +43,18 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferSlots, :config do
|
|
|
79
43
|
RUBY
|
|
80
44
|
end
|
|
81
45
|
|
|
82
|
-
it "does not register offense for
|
|
46
|
+
it "does not register offense for _content suffix" do
|
|
47
|
+
expect_no_offenses(<<~RUBY)
|
|
48
|
+
class CardComponent < ViewComponent::Base
|
|
49
|
+
def initialize(title:, fit_content: false)
|
|
50
|
+
@title = title
|
|
51
|
+
@fit_content = fit_content
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
RUBY
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "does not register offense for html_ prefix" do
|
|
83
58
|
expect_no_offenses(<<~RUBY)
|
|
84
59
|
class CardComponent < ViewComponent::Base
|
|
85
60
|
def initialize(title:, html_class:)
|
|
@@ -89,6 +64,17 @@ RSpec.describe RuboCop::Cop::ViewComponent::PreferSlots, :config do
|
|
|
89
64
|
end
|
|
90
65
|
RUBY
|
|
91
66
|
end
|
|
67
|
+
|
|
68
|
+
it "does not register offense for content parameter" do
|
|
69
|
+
expect_no_offenses(<<~RUBY)
|
|
70
|
+
class CardComponent < ViewComponent::Base
|
|
71
|
+
def initialize(title:, content:)
|
|
72
|
+
@title = title
|
|
73
|
+
@content = content
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
RUBY
|
|
77
|
+
end
|
|
92
78
|
end
|
|
93
79
|
|
|
94
80
|
context "when not a ViewComponent" do
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe RuboCop::Cop::ViewComponent::TestRenderedOutput, :config do
|
|
4
|
+
let(:config) { RuboCop::Config.new }
|
|
5
|
+
|
|
6
|
+
context "with Minitest-style tests" do
|
|
7
|
+
context "when test instantiates a component but doesn't render" do
|
|
8
|
+
it "registers an offense" do
|
|
9
|
+
expect_offense(<<~RUBY)
|
|
10
|
+
def test_formatted_title
|
|
11
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ ViewComponent/TestRenderedOutput: Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
12
|
+
component = UserComponent.new("hello")
|
|
13
|
+
assert_equal "HELLO", component.formatted_title
|
|
14
|
+
end
|
|
15
|
+
RUBY
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "when test instantiates a non-Component-suffixed class" do
|
|
20
|
+
it "registers an offense" do
|
|
21
|
+
expect_offense(<<~RUBY)
|
|
22
|
+
def test_toggle
|
|
23
|
+
^^^^^^^^^^^^^^^ ViewComponent/TestRenderedOutput: Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
24
|
+
component = V2::Toggle.new
|
|
25
|
+
assert component.active?
|
|
26
|
+
end
|
|
27
|
+
RUBY
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "when test instantiates a component and uses render_inline" do
|
|
32
|
+
it "does not register an offense" do
|
|
33
|
+
expect_no_offenses(<<~RUBY)
|
|
34
|
+
def test_formatted_title
|
|
35
|
+
render_inline UserComponent.new("hello")
|
|
36
|
+
assert_text "HELLO"
|
|
37
|
+
end
|
|
38
|
+
RUBY
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when test instantiates a component and uses render_preview" do
|
|
43
|
+
it "does not register an offense" do
|
|
44
|
+
expect_no_offenses(<<~RUBY)
|
|
45
|
+
def test_preview
|
|
46
|
+
render_preview(:default)
|
|
47
|
+
assert_selector ".component"
|
|
48
|
+
end
|
|
49
|
+
RUBY
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "when test doesn't instantiate any constants" do
|
|
54
|
+
it "does not register an offense" do
|
|
55
|
+
expect_no_offenses(<<~RUBY)
|
|
56
|
+
def test_helper_method
|
|
57
|
+
result = some_method("hello")
|
|
58
|
+
assert_equal "HELLO", result
|
|
59
|
+
end
|
|
60
|
+
RUBY
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "when test uses with_ configuration methods" do
|
|
65
|
+
it "does not register an offense" do
|
|
66
|
+
expect_no_offenses(<<~RUBY)
|
|
67
|
+
def test_with_content
|
|
68
|
+
render_inline(UserComponent.new.with_content("Button"))
|
|
69
|
+
assert_text "Button"
|
|
70
|
+
end
|
|
71
|
+
RUBY
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "when method doesn't start with test_" do
|
|
76
|
+
it "does not register an offense even with component instantiation" do
|
|
77
|
+
expect_no_offenses(<<~RUBY)
|
|
78
|
+
def helper_method
|
|
79
|
+
component = UserComponent.new("hello")
|
|
80
|
+
component.formatted_title
|
|
81
|
+
end
|
|
82
|
+
RUBY
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context "when test instantiates a namespaced component" do
|
|
87
|
+
it "registers an offense" do
|
|
88
|
+
expect_offense(<<~RUBY)
|
|
89
|
+
def test_namespaced
|
|
90
|
+
^^^^^^^^^^^^^^^^^^^ ViewComponent/TestRenderedOutput: Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
91
|
+
component = Admin::UserComponent.new("hello")
|
|
92
|
+
assert_equal "HELLO", component.formatted_title
|
|
93
|
+
end
|
|
94
|
+
RUBY
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
context "with TestPaths configured" do
|
|
100
|
+
let(:config) do
|
|
101
|
+
RuboCop::Config.new(
|
|
102
|
+
"AllCops" => {"DisplayCopNames" => true},
|
|
103
|
+
"ViewComponent/TestRenderedOutput" => {
|
|
104
|
+
"TestPaths" => ["spec/components/v2/"]
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context "when file is within a configured TestPath" do
|
|
110
|
+
it "registers an offense" do
|
|
111
|
+
expect_offense(<<~RUBY, "spec/components/v2/button_component_spec.rb")
|
|
112
|
+
def test_formatted_title
|
|
113
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ ViewComponent/TestRenderedOutput: Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
114
|
+
component = UserComponent.new("hello")
|
|
115
|
+
assert_equal "HELLO", component.formatted_title
|
|
116
|
+
end
|
|
117
|
+
RUBY
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "when file is outside all configured TestPaths" do
|
|
122
|
+
it "does not register an offense" do
|
|
123
|
+
expect_no_offenses(<<~RUBY, "spec/components/v1/button_component_spec.rb")
|
|
124
|
+
def test_formatted_title
|
|
125
|
+
component = UserComponent.new("hello")
|
|
126
|
+
assert_equal "HELLO", component.formatted_title
|
|
127
|
+
end
|
|
128
|
+
RUBY
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
context "with RSpec-style tests" do
|
|
134
|
+
context "when it block instantiates a component but doesn't render" do
|
|
135
|
+
it "registers an offense" do
|
|
136
|
+
expect_offense(<<~RUBY)
|
|
137
|
+
it "formats the title" do
|
|
138
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^ ViewComponent/TestRenderedOutput: Test instantiates a component but doesn't use `render_inline` or `render_preview`. Test the rendered output instead of component methods directly.
|
|
139
|
+
component = UserComponent.new("hello")
|
|
140
|
+
expect(component.formatted_title).to eq("HELLO")
|
|
141
|
+
end
|
|
142
|
+
RUBY
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "when it block instantiates a component and uses render_inline" do
|
|
147
|
+
it "does not register an offense" do
|
|
148
|
+
expect_no_offenses(<<~RUBY)
|
|
149
|
+
it "formats the title" do
|
|
150
|
+
render_inline UserComponent.new("hello")
|
|
151
|
+
expect(page).to have_text("HELLO")
|
|
152
|
+
end
|
|
153
|
+
RUBY
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
context "when it block doesn't instantiate components" do
|
|
158
|
+
it "does not register an offense" do
|
|
159
|
+
expect_no_offenses(<<~RUBY)
|
|
160
|
+
it "formats the name" do
|
|
161
|
+
result = some_method("hello")
|
|
162
|
+
expect(result).to eq("HELLO")
|
|
163
|
+
end
|
|
164
|
+
RUBY
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
primer:
|
|
2
|
+
tarball_url: https://github.com/primer/view_components/archive/refs/heads/main.tar.gz
|
|
3
|
+
display_name: primer/view_components
|
|
4
|
+
|
|
5
|
+
govuk:
|
|
6
|
+
tarball_url: https://github.com/x-govuk/govuk-components/archive/refs/heads/main.tar.gz
|
|
7
|
+
display_name: x-govuk/govuk-components
|
|
8
|
+
|
|
9
|
+
polaris:
|
|
10
|
+
tarball_url: https://github.com/baoagency/polaris_view_components/archive/refs/heads/main.tar.gz
|
|
11
|
+
display_name: baoagency/polaris_view_components
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
ViewComponentParentClasses:
|
|
3
|
+
- Primer::Component
|
|
4
|
+
- Primer::BaseComponent
|
|
5
|
+
|
|
6
|
+
# Primer seems to intentionally omit the Component suffix from most class names
|
|
7
|
+
# (116 out of 131 components), so this cop is not useful here.
|
|
8
|
+
ViewComponent/ComponentSuffix:
|
|
9
|
+
Enabled: false
|
|
10
|
+
|
|
11
|
+
# Primer::Forms::BaseComponent is not a ViewComponent - it's a custom base class
|
|
12
|
+
# for a forms framework that mimics the component interface but doesn't inherit
|
|
13
|
+
# from ViewComponent::Base
|
|
14
|
+
ViewComponent/PreferComposition:
|
|
15
|
+
Exclude:
|
|
16
|
+
- app/lib/primer/forms/**/*
|
|
17
|
+
- test/lib/primer/forms/**/*
|
|
18
|
+
|
|
19
|
+
# These tests intentionally test internal implementation details or helper methods
|
|
20
|
+
ViewComponent/TestRenderedOutput:
|
|
21
|
+
Exclude:
|
|
22
|
+
- test/components/base_component_test.rb
|
|
23
|
+
- test/components/component_test.rb
|
|
24
|
+
- test/lib/primer/attributes_helper_test.rb
|