rubocop-discourse 3.1.0 → 3.9.3

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +2 -2
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +7 -0
  5. data/config/default.yml +51 -24
  6. data/lib/rubocop/cop/discourse/fabricator_shorthand.rb +62 -0
  7. data/lib/rubocop/cop/discourse/no_add_reference_active_record_migrations.rb +9 -7
  8. data/lib/rubocop/cop/discourse/no_chdir.rb +1 -1
  9. data/lib/rubocop/cop/discourse/no_direct_multisite_manipulation.rb +3 -2
  10. data/lib/rubocop/cop/discourse/no_json_parse_response.rb +2 -4
  11. data/lib/rubocop/cop/discourse/no_mixing_multisite_and_standard_specs.rb +4 -7
  12. data/lib/rubocop/cop/discourse/no_mocking_jobs.rb +3 -2
  13. data/lib/rubocop/cop/discourse/no_nokogiri_html_fragment.rb +1 -1
  14. data/lib/rubocop/cop/discourse/no_reset_column_information_in_migrations.rb +6 -5
  15. data/lib/rubocop/cop/discourse/no_time_new_without_args.rb +2 -4
  16. data/lib/rubocop/cop/discourse/no_uri_escape_encode.rb +11 -8
  17. data/lib/rubocop/cop/discourse/only_top_level_multisite_specs.rb +2 -6
  18. data/lib/rubocop/cop/discourse/plugins/call_requires_plugin.rb +71 -0
  19. data/lib/rubocop/cop/discourse/plugins/namespace_constants.rb +35 -0
  20. data/lib/rubocop/cop/discourse/plugins/namespace_methods.rb +37 -0
  21. data/lib/rubocop/cop/discourse/plugins/no_monkey_patching.rb +92 -0
  22. data/lib/rubocop/cop/discourse/plugins/use_plugin_instance_on.rb +42 -0
  23. data/lib/rubocop/cop/discourse/plugins/use_require_relative.rb +32 -0
  24. data/lib/rubocop/cop/discourse/services/empty_lines_around_blocks.rb +114 -0
  25. data/lib/rubocop/cop/discourse/services/group_keywords.rb +92 -0
  26. data/lib/rubocop/cop/discourse/time_eq_matcher.rb +2 -4
  27. data/lib/rubocop/cop/discourse_cops.rb +1 -1
  28. data/lib/rubocop/discourse.rb +3 -3
  29. data/lib/rubocop-discourse.rb +4 -0
  30. data/rubocop-capybara.yml +5 -0
  31. data/rubocop-core.yml +81 -4
  32. data/rubocop-discourse.gemspec +15 -10
  33. data/rubocop-factory_bot.yml +11 -0
  34. data/rubocop-layout.yml +4 -0
  35. data/rubocop-rails.yml +14 -0
  36. data/rubocop-rspec.yml +29 -23
  37. data/spec/fixtures/controllers/bad_controller.rb +5 -0
  38. data/spec/fixtures/controllers/base_controller.rb +11 -0
  39. data/spec/fixtures/controllers/good_controller.rb +4 -0
  40. data/spec/fixtures/controllers/inherit_from_outside_controller.rb +5 -0
  41. data/spec/fixtures/controllers/namespaced_parent_controller.rb +5 -0
  42. data/spec/fixtures/controllers/no_requires_plugin_controller.rb +5 -0
  43. data/spec/fixtures/controllers/requires_plugin_controller.rb +6 -0
  44. data/spec/lib/rubocop/cop/discourse/services/empty_lines_around_blocks_spec.rb +309 -0
  45. data/spec/lib/rubocop/cop/discourse/services/group_keywords_spec.rb +137 -0
  46. data/spec/lib/rubocop/cop/fabricator_shorthand_spec.rb +47 -0
  47. data/spec/lib/rubocop/cop/no_add_reference_active_record_migrations_spec.rb +13 -16
  48. data/spec/lib/rubocop/cop/no_mixing_multisite_and_standard_specs_spec.rb +10 -14
  49. data/spec/lib/rubocop/cop/no_mocking_jobs_enqueue_spec.rb +8 -12
  50. data/spec/lib/rubocop/cop/no_reset_column_information_migrations_spec.rb +8 -10
  51. data/spec/lib/rubocop/cop/only_top_level_multisite_specs_spec.rb +14 -18
  52. data/spec/lib/rubocop/cop/plugins/call_requires_plugin_spec.rb +79 -0
  53. data/spec/lib/rubocop/cop/plugins/namespace_constants_spec.rb +40 -0
  54. data/spec/lib/rubocop/cop/plugins/namespace_methods_spec.rb +84 -0
  55. data/spec/lib/rubocop/cop/plugins/no_monkey_patching_spec.rb +91 -0
  56. data/spec/lib/rubocop/cop/plugins/use_plugin_instance_on_spec.rb +37 -0
  57. data/spec/lib/rubocop/cop/plugins/use_require_relative_spec.rb +24 -0
  58. data/spec/lib/rubocop/cop/time_eq_matcher_spec.rb +6 -10
  59. data/spec/spec_helper.rb +4 -4
  60. data/stree-compat.yml +10 -1
  61. metadata +110 -16
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Discourse
6
+ module Plugins
7
+ # Using `DiscourseEvent.on` leaves the handler enabled when the plugin is disabled.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # DiscourseEvent.on(:event) { do_something }
12
+ #
13
+ # # good
14
+ # on(:event) { do_something }
15
+ #
16
+ class UsePluginInstanceOn < Base
17
+ MSG =
18
+ "Use `on` instead of `DiscourseEvent.on` as the latter will listen to events even if the plugin is disabled."
19
+ NOT_OUTSIDE_PLUGIN_RB =
20
+ "Don’t call `DiscourseEvent.on` outside `plugin.rb`."
21
+ RESTRICT_ON_SEND = [:on].freeze
22
+
23
+ def_node_matcher :discourse_event_on?, <<~MATCHER
24
+ (send (const nil? :DiscourseEvent) :on _)
25
+ MATCHER
26
+
27
+ def on_send(node)
28
+ return unless discourse_event_on?(node)
29
+ return add_offense(node, message: MSG) if in_plugin_rb_file?
30
+ add_offense(node, message: NOT_OUTSIDE_PLUGIN_RB)
31
+ end
32
+
33
+ private
34
+
35
+ def in_plugin_rb_file?
36
+ processed_source.path.split("/").last == "plugin.rb"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Discourse
6
+ module Plugins
7
+ # Use `require_relative` to load dependencies.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # load File.expand_path("../lib/my_file.rb", __FILE__)
12
+ #
13
+ # # good
14
+ # require_relative "lib/my_file"
15
+ #
16
+ class UseRequireRelative < Base
17
+ MSG = "Use `require_relative` instead of `load`."
18
+ RESTRICT_ON_SEND = [:load].freeze
19
+
20
+ def_node_matcher :load_called?, <<~MATCHER
21
+ (send nil? :load _)
22
+ MATCHER
23
+
24
+ def on_send(node)
25
+ return unless load_called?(node)
26
+ add_offense(node, message: MSG)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Discourse
6
+ module Services
7
+ # Put empty lines around multiline blocks.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # model :my_model
12
+ # params do
13
+ # attribute :my_attribute
14
+ # validates :my_attribute, presence: true
15
+ # end
16
+ # policy :my_policy
17
+ # step :another_step
18
+ #
19
+ # # good
20
+ # model :my_model
21
+ #
22
+ # params do
23
+ # attribute :my_attribute
24
+ # validates :my_attribute, presence: true
25
+ # end
26
+ #
27
+ # policy :my_policy
28
+ # step :another_step
29
+ #
30
+ class EmptyLinesAroundBlocks < Base
31
+ extend AutoCorrector
32
+
33
+ MSG = "Add empty lines around a step block."
34
+
35
+ def_node_matcher :service_include?, <<~MATCHER
36
+ (class _ _
37
+ {
38
+ (begin <(send nil? :include (const (const nil? :Service) :Base)) ...>)
39
+ <(send nil? :include (const (const nil? :Service) :Base)) ...>
40
+ }
41
+ )
42
+ MATCHER
43
+
44
+ def_node_matcher :top_level_block?, <<~MATCHER
45
+ (block (send nil? _) ...)
46
+ MATCHER
47
+
48
+ def on_class(node)
49
+ return unless service_include?(node)
50
+ @service = true
51
+ end
52
+
53
+ def on_block(node)
54
+ return unless service?
55
+ return unless top_level_block?(node)
56
+ return if node.single_line? || single_block?(node)
57
+
58
+ if missing_empty_lines?(node)
59
+ add_offense(node, message: MSG) do |corrector|
60
+ if missing_empty_line_before?(node) &&
61
+ corrected_after.exclude?(node.left_sibling)
62
+ corrected_before << node
63
+ corrector.insert_before(
64
+ node.loc.expression.adjust(
65
+ begin_pos: -node.loc.expression.column
66
+ ),
67
+ "\n"
68
+ )
69
+ end
70
+ if missing_empty_line_after?(node) &&
71
+ corrected_before.exclude?(node.right_sibling)
72
+ corrected_after << node
73
+ corrector.insert_after(node.loc.end, "\n")
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def single_block?(node)
82
+ !node.ancestors.first.begin_type?
83
+ end
84
+
85
+ def service?
86
+ @service
87
+ end
88
+
89
+ def missing_empty_lines?(node)
90
+ missing_empty_line_before?(node) || missing_empty_line_after?(node)
91
+ end
92
+
93
+ def missing_empty_line_before?(node)
94
+ processed_source[node.loc.expression.line - 2].present? &&
95
+ node.left_siblings.present?
96
+ end
97
+
98
+ def missing_empty_line_after?(node)
99
+ processed_source[node.loc.end.line].present? &&
100
+ node.right_siblings.present?
101
+ end
102
+
103
+ def corrected_before
104
+ @corrected_before ||= []
105
+ end
106
+
107
+ def corrected_after
108
+ @corrected_before ||= []
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Discourse
6
+ module Services
7
+ # Don’t put empty lines between keywords that are not multiline blocks.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # model :my_model
12
+ #
13
+ # policy :my_policy
14
+ #
15
+ # try { step :might_raise }
16
+ #
17
+ # # good
18
+ # model :my_model
19
+ # policy :my_policy
20
+ # try { step :might_raise }
21
+ #
22
+ class GroupKeywords < Base
23
+ extend AutoCorrector
24
+
25
+ MSG = "Group one-liner steps together by removing extra empty lines."
26
+ RESTRICT_ON_SEND = %i[step model policy].freeze
27
+
28
+ def_node_matcher :service_include?, <<~MATCHER
29
+ (class _ _
30
+ {
31
+ (begin <(send nil? :include (const (const nil? :Service) :Base)) ...>)
32
+ <(send nil? :include (const (const nil? :Service) :Base)) ...>
33
+ }
34
+ )
35
+ MATCHER
36
+
37
+ def on_class(node)
38
+ return unless service_include?(node)
39
+ @service = true
40
+ end
41
+
42
+ def on_send(node)
43
+ return unless service?
44
+ return unless top_level?(node)
45
+ return unless extra_empty_line_after?(node)
46
+
47
+ add_offense(node, message: MSG) do |corrector|
48
+ range =
49
+ node.loc.expression.end.with(
50
+ end_pos: node.right_sibling.loc.expression.begin_pos
51
+ )
52
+ content = range.source.gsub(/^(\n)+/, "\n")
53
+ corrector.replace(range, content)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def service?
60
+ @service
61
+ end
62
+
63
+ def extra_empty_line_after?(node)
64
+ processed_source[node.loc.expression.line].blank? &&
65
+ (
66
+ service_keyword?(node.right_sibling) ||
67
+ single_line_block?(node.right_sibling)
68
+ )
69
+ end
70
+
71
+ def service_keyword?(node)
72
+ return unless node
73
+ node.send_type? && RESTRICT_ON_SEND.include?(node.method_name)
74
+ end
75
+
76
+ def single_line_block?(node)
77
+ return unless node
78
+ node.block_type? && node.single_line?
79
+ end
80
+
81
+ def top_level?(node)
82
+ while (!node.root?)
83
+ node = node.parent
84
+ return if %i[begin class block].exclude?(node.type)
85
+ end
86
+ true
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -11,7 +11,7 @@ module RuboCop
11
11
  #
12
12
  # # good
13
13
  # expect(user.created_at).to eq_time(Time.zone.now)
14
- class TimeEqMatcher < Cop
14
+ class TimeEqMatcher < Base
15
15
  MSG = "Use eq_time when testing timestamps"
16
16
 
17
17
  def_node_matcher :using_eq_matcher_with_timestamp?, <<-MATCHER
@@ -29,9 +29,7 @@ module RuboCop
29
29
  end
30
30
 
31
31
  def autocorrect(node)
32
- lambda do |corrector|
33
- corrector.replace(node.children.last.loc.selector, "eq_time")
34
- end
32
+ lambda { |corrector| corrector.replace(node.children.last.loc.selector, "eq_time") }
35
33
  end
36
34
 
37
35
  private
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- path = File.join(__dir__, "discourse", "*.rb")
3
+ path = File.join(__dir__, "discourse", "**/*.rb")
4
4
  Dir[path].each { |file| require file }
@@ -3,9 +3,9 @@
3
3
  module RuboCop
4
4
  # RuboCop Discourse project namespace
5
5
  module Discourse
6
- PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
- CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze
8
- CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
6
+ PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
7
+ CONFIG_DEFAULT = PROJECT_ROOT.join("config", "default.yml").freeze
8
+ CONFIG = YAML.safe_load(CONFIG_DEFAULT.read).freeze
9
9
 
10
10
  private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
11
11
  end
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rubocop"
4
+ require "active_support"
5
+ require "active_support/core_ext/string/inflections"
6
+ require "active_support/core_ext/object/blank"
7
+ require "active_support/core_ext/enumerable"
4
8
  require_relative "rubocop/discourse"
5
9
  require_relative "rubocop/discourse/inject"
6
10
 
@@ -0,0 +1,5 @@
1
+ require:
2
+ - rubocop-capybara
3
+
4
+ Capybara/CurrentPathExpectation:
5
+ Enabled: true
data/rubocop-core.yml CHANGED
@@ -4,6 +4,9 @@ Security:
4
4
  Security/IoMethods:
5
5
  Enabled: true
6
6
 
7
+ Security/CompoundHash:
8
+ Enabled: true
9
+
7
10
  # Prefer &&/|| over and/or.
8
11
  Style/AndOr:
9
12
  Enabled: true
@@ -14,6 +17,7 @@ Style/FrozenStringLiteralComment:
14
17
  # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
15
18
  Style/HashSyntax:
16
19
  Enabled: true
20
+ EnforcedShorthandSyntax: either
17
21
 
18
22
  # Defining a method with parameters needs parentheses.
19
23
  Style/MethodDefParentheses:
@@ -33,10 +37,9 @@ Style/GlobalVars:
33
37
  Enabled: true
34
38
  Severity: warning
35
39
  Exclude:
36
- - 'lib/tasks/**/*'
37
- - 'script/**/*'
38
- - 'spec/**/*.rb'
39
- - 'plugins/*/spec/**/*'
40
+ - "lib/tasks/**/*"
41
+ - "script/**/*"
42
+ - "**/spec/**/*"
40
43
 
41
44
  Style/InvertibleUnlessCondition:
42
45
  Enabled: true
@@ -65,3 +68,77 @@ Bundler/OrderedGems:
65
68
 
66
69
  Layout/LineLength:
67
70
  Enabled: false
71
+
72
+ Lint/ParenthesesAsGroupedExpression:
73
+ Enabled: true
74
+
75
+ Lint/DuplicateMethods:
76
+ Enabled: true
77
+
78
+ Lint/RedundantWithIndex:
79
+ Enabled: true
80
+
81
+ Lint/RedundantRequireStatement:
82
+ Enabled: true
83
+
84
+ Lint/LiteralInInterpolation:
85
+ Enabled: true
86
+
87
+ Lint/RedundantStringCoercion:
88
+ Enabled: true
89
+
90
+ Lint/BooleanSymbol:
91
+ Enabled: true
92
+ AutoCorrect: false # it breaks the code
93
+
94
+ Lint/ShadowedArgument:
95
+ Enabled: true
96
+
97
+ Lint/RedundantCopDisableDirective:
98
+ Enabled: true
99
+
100
+ Lint/EmptyEnsure:
101
+ Enabled: true
102
+
103
+ Lint/RedundantWithObject:
104
+ Enabled: true
105
+
106
+ Lint/SelfAssignment:
107
+ Enabled: true
108
+
109
+ Lint/Void:
110
+ Enabled: true
111
+
112
+ Lint/UselessMethodDefinition:
113
+ Enabled: true
114
+
115
+ Lint/UnreachableCode:
116
+ Enabled: true
117
+
118
+ Lint/DeprecatedOpenSSLConstant:
119
+ Enabled: true
120
+
121
+ Lint/DisjunctiveAssignmentInConstructor:
122
+ Enabled: true
123
+
124
+ Lint/NonLocalExitFromIterator:
125
+ Enabled: true
126
+
127
+ Lint/DeprecatedClassMethods:
128
+ Enabled: true
129
+
130
+ Lint/SafeNavigationChain:
131
+ Enabled: true
132
+
133
+ Lint/RedundantSafeNavigation:
134
+ Enabled: true
135
+
136
+ Lint/EmptyConditionalBody:
137
+ Enabled: true
138
+ AutoCorrect: false # it can break the code
139
+
140
+ Lint/SafeNavigationConsistency:
141
+ Enabled: true
142
+
143
+ Lint/OrAssignmentToConstant:
144
+ Enabled: true
@@ -1,19 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Gem::Specification.new do |s|
4
- s.name = "rubocop-discourse"
5
- s.version = "3.1.0"
6
- s.summary = "Custom rubocop cops used by Discourse"
7
- s.authors = ["Discourse Team"]
8
- s.license = "MIT"
9
- s.homepage = "https://github.com/discourse/rubocop-discourse"
4
+ s.name = "rubocop-discourse"
5
+ s.version = "3.9.3"
6
+ s.summary = "Custom rubocop cops used by Discourse"
7
+ s.authors = ["Discourse Team"]
8
+ s.license = "MIT"
9
+ s.homepage = "https://github.com/discourse/rubocop-discourse"
10
10
 
11
11
  s.files = `git ls-files`.split($/)
12
12
  s.require_paths = ["lib"]
13
13
 
14
- s.add_runtime_dependency "rubocop", ">= 1.1.0"
15
- s.add_runtime_dependency "rubocop-rspec", ">= 2.0.0"
14
+ s.add_runtime_dependency "activesupport", ">= 6.1"
15
+ s.add_runtime_dependency "rubocop", ">= 1.59.0"
16
+ s.add_runtime_dependency "rubocop-rspec", ">= 3.0.1"
17
+ s.add_runtime_dependency "rubocop-factory_bot", ">= 2.0.0"
18
+ s.add_runtime_dependency "rubocop-capybara", ">= 2.0.0"
19
+ s.add_runtime_dependency "rubocop-rails", ">= 2.25.0"
20
+ s.add_runtime_dependency "rubocop-rspec_rails", ">= 2.30.0"
16
21
 
17
- s.add_development_dependency "rake", "~> 13.0"
18
- s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rake", "~> 13.1.0"
23
+ s.add_development_dependency "rspec", "~> 3.12.0"
19
24
  end
@@ -0,0 +1,11 @@
1
+ require:
2
+ - rubocop-factory_bot
3
+
4
+ FactoryBot/AttributeDefinedStatically:
5
+ Enabled: true
6
+
7
+ FactoryBot/CreateList:
8
+ Enabled: true
9
+
10
+ FactoryBot/FactoryClassName:
11
+ Enabled: true
data/rubocop-layout.yml CHANGED
@@ -10,6 +10,10 @@ Layout/CommentIndentation:
10
10
  Layout/EmptyLines:
11
11
  Enabled: true
12
12
 
13
+ # Use empty lines between definitions.
14
+ Layout/EmptyLineBetweenDefs:
15
+ Enabled: true
16
+
13
17
  # Two spaces, no tabs (for indentation).
14
18
  Layout/IndentationWidth:
15
19
  Enabled: true
data/rubocop-rails.yml ADDED
@@ -0,0 +1,14 @@
1
+ require:
2
+ - rubocop-rails
3
+
4
+ Rails:
5
+ Enabled: false
6
+
7
+ Rails/EnumHash:
8
+ Enabled: true
9
+
10
+ Rails/EnumUniqueness:
11
+ Enabled: true
12
+
13
+ Rails/ReversibleMigrationMethodDefinition:
14
+ Enabled: true
data/rubocop-rspec.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  require:
2
2
  - rubocop-rspec
3
+ - rubocop-rspec_rails
3
4
 
4
5
  RSpec/AnyInstance:
5
6
  Enabled: false # To be decided
@@ -27,6 +28,7 @@ RSpec/ContextWording:
27
28
  - if
28
29
  - as
29
30
  - after
31
+ - in
30
32
 
31
33
  RSpec/DescribeClass:
32
34
  Enabled: true
@@ -53,12 +55,12 @@ RSpec/DescribedClass:
53
55
  Enabled: false # To be decided
54
56
 
55
57
  RSpec/DescribedClassModuleWrapping:
56
- Enabled: false # To be decided
58
+ Enabled: true
57
59
 
58
60
  RSpec/EmptyExampleGroup:
59
61
  Enabled: true
60
62
  Exclude:
61
- - 'spec/requests/api/*'
63
+ - "spec/requests/api/*"
62
64
 
63
65
  RSpec/EmptyLineAfterExample:
64
66
  Enabled: false # TODO
@@ -73,7 +75,7 @@ RSpec/EmptyLineAfterHook:
73
75
  Enabled: false # TODO
74
76
 
75
77
  RSpec/EmptyLineAfterSubject:
76
- Enabled: false # TODO
78
+ Enabled: true
77
79
 
78
80
  RSpec/ExampleLength:
79
81
  Enabled: false # To be decided
@@ -91,14 +93,17 @@ RSpec/ExpectChange:
91
93
  Enabled: false # To be decided
92
94
 
93
95
  RSpec/ExpectInHook:
94
- Enabled: false # To be decided
96
+ Enabled: false
95
97
 
96
98
  RSpec/ExpectOutput:
97
99
  Enabled: true
98
100
 
99
- RSpec/FilePath:
101
+ RSpec/SpecFilePathFormat:
100
102
  Enabled: false # To be decided
101
103
 
104
+ RSpec/SpecFilePathSuffix:
105
+ Enabled: true
106
+
102
107
  RSpec/Focus:
103
108
  Enabled: true
104
109
 
@@ -130,7 +135,7 @@ RSpec/IteratedExpectation:
130
135
  Enabled: false # To be decided
131
136
 
132
137
  RSpec/LeadingSubject:
133
- Enabled: false # TODO
138
+ Enabled: true
134
139
 
135
140
  RSpec/LeakyConstantDeclaration:
136
141
  Enabled: false # To be decided
@@ -150,14 +155,20 @@ RSpec/MessageSpies:
150
155
  RSpec/MissingExampleGroupArgument:
151
156
  Enabled: true
152
157
 
158
+ RSpec/MultipleExpectations:
159
+ Enabled: false
160
+
153
161
  RSpec/MultipleDescribes:
154
162
  Enabled: false # TODO
155
163
 
164
+ RSpec/MultipleMemoizedHelpers:
165
+ Enabled: false
166
+
156
167
  RSpec/MultipleSubjects:
157
168
  Enabled: true
158
169
 
159
170
  RSpec/NamedSubject:
160
- Enabled: false # To be decided
171
+ Enabled: true
161
172
 
162
173
  RSpec/NestedGroups:
163
174
  Enabled: false # To be decided
@@ -172,7 +183,7 @@ RSpec/ReceiveNever:
172
183
  Enabled: true
173
184
 
174
185
  RSpec/RepeatedDescription:
175
- Enabled: false # TODO
186
+ Enabled: false
176
187
 
177
188
  RSpec/RepeatedExample:
178
189
  Enabled: false # TODO
@@ -181,7 +192,7 @@ RSpec/RepeatedExampleGroupBody:
181
192
  Enabled: false # TODO
182
193
 
183
194
  RSpec/RepeatedExampleGroupDescription:
184
- Enabled: false # TODO
195
+ Enabled: false
185
196
 
186
197
  RSpec/ReturnFromStub:
187
198
  Enabled: true
@@ -213,20 +224,15 @@ RSpec/VoidExpect:
213
224
  RSpec/Yield:
214
225
  Enabled: true
215
226
 
216
- RSpec/Capybara/CurrentPathExpectation:
217
- Enabled: true
218
-
219
- RSpec/Capybara/FeatureMethods:
220
- Enabled: true
221
-
222
- RSpec/FactoryBot/AttributeDefinedStatically:
223
- Enabled: true
224
-
225
- RSpec/FactoryBot/CreateList:
226
- Enabled: true
227
-
228
- RSpec/FactoryBot/FactoryClassName:
227
+ RSpec/Dialect:
229
228
  Enabled: true
229
+ PreferredMethods:
230
+ background: :before
231
+ scenario: :it
232
+ xscenario: :xit
233
+ given: :let
234
+ given!: :let!
235
+ feature: :describe
230
236
 
231
- RSpec/Rails/HttpStatus:
237
+ RSpecRails/HttpStatus:
232
238
  Enabled: true
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BadController < NoRequiresPluginController
4
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/CallRequiresPlugin: Use `requires_plugin` in controllers to prevent routes from being accessible when plugin is disabled.
5
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BaseController
4
+ class << self
5
+ def requires_plugin(*)
6
+ end
7
+
8
+ def requires_login
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class GoodController < RequiresPluginController
4
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class InheritFromOutsideController < ApplicationController
4
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/CallRequiresPlugin: Use `requires_plugin` in controllers to prevent routes from being accessible when plugin is disabled.
5
+ end