rubocop-discourse 3.6.0 → 3.7.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/.rubocop.yml +7 -0
- data/config/default.yml +28 -0
- data/lib/rubocop/cop/discourse/fabricator_shorthand.rb +52 -0
- data/lib/rubocop/cop/discourse/plugins/call_requires_plugin.rb +71 -0
- data/lib/rubocop/cop/discourse/plugins/namespace_constants.rb +35 -0
- data/lib/rubocop/cop/discourse/plugins/namespace_methods.rb +37 -0
- data/lib/rubocop/cop/discourse/plugins/no_monkey_patching.rb +92 -0
- data/lib/rubocop/cop/discourse/plugins/use_plugin_instance_on.rb +42 -0
- data/lib/rubocop/cop/discourse/plugins/use_require_relative.rb +32 -0
- data/lib/rubocop/cop/discourse_cops.rb +1 -1
- data/lib/rubocop-discourse.rb +2 -0
- data/rubocop-capybara.yml +5 -0
- data/rubocop-core.yml +1 -0
- data/rubocop-discourse.gemspec +4 -1
- data/rubocop-factory_bot.yml +11 -0
- data/rubocop-rspec.yml +0 -15
- data/spec/fixtures/controllers/bad_controller.rb +5 -0
- data/spec/fixtures/controllers/base_controller.rb +11 -0
- data/spec/fixtures/controllers/good_controller.rb +4 -0
- data/spec/fixtures/controllers/inherit_from_outside_controller.rb +5 -0
- data/spec/fixtures/controllers/namespaced_parent_controller.rb +5 -0
- data/spec/fixtures/controllers/no_requires_plugin_controller.rb +5 -0
- data/spec/fixtures/controllers/requires_plugin_controller.rb +6 -0
- data/spec/lib/rubocop/cop/fabricator_shorthand_spec.rb +34 -0
- data/spec/lib/rubocop/cop/plugins/call_requires_plugin_spec.rb +81 -0
- data/spec/lib/rubocop/cop/plugins/namespace_constants_spec.rb +42 -0
- data/spec/lib/rubocop/cop/plugins/namespace_methods_spec.rb +86 -0
- data/spec/lib/rubocop/cop/plugins/no_monkey_patching_spec.rb +93 -0
- data/spec/lib/rubocop/cop/plugins/use_plugin_instance_on_spec.rb +39 -0
- data/spec/lib/rubocop/cop/plugins/use_require_relative_spec.rb +26 -0
- data/stree-compat.yml +8 -0
- metadata +67 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d347009b4a77b64450a20ef3afc5ca102dd361c60e3fbde2e5fd0ea976469cd
|
4
|
+
data.tar.gz: c98b24bd73f783f154320e337e44f6859e050c43ff9219cfa0be6f63a891fc13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98c56b4b42703f8fc1fe0b3f68344507e2001d7a71d5530c89b8f21a29b5276fc518542b445e9dd9a902cb30be38ce0d4df18218b2cf08bfb50465411d7c7d77
|
7
|
+
data.tar.gz: f7f5f50325374fe530a26c20ed113b4cb827ed7541a8a9f6dbae1a81c0dca29be2cc7073c8f543b5200dab2e2238617984a7f4dbd87d838ff8a1d4cfa8da0db6
|
data/.rubocop.yml
CHANGED
data/config/default.yml
CHANGED
@@ -62,3 +62,31 @@ Discourse/NoMixingMultisiteAndStandardSpecs:
|
|
62
62
|
Patterns:
|
63
63
|
- _spec.rb
|
64
64
|
- '(?:^|/)spec/'
|
65
|
+
|
66
|
+
Discourse/Plugins/CallRequiresPlugin:
|
67
|
+
Enabled: true
|
68
|
+
Include:
|
69
|
+
- 'app/controllers/**/*'
|
70
|
+
|
71
|
+
Discourse/Plugins/UsePluginInstanceOn:
|
72
|
+
Enabled: true
|
73
|
+
|
74
|
+
Discourse/Plugins/NamespaceMethods:
|
75
|
+
Enabled: true
|
76
|
+
Exclude:
|
77
|
+
- '**/spec/**/*'
|
78
|
+
- '**/tasks/**/*.rake'
|
79
|
+
- '**/db/fixtures/**/*'
|
80
|
+
|
81
|
+
Discourse/Plugins/NamespaceConstants:
|
82
|
+
Enabled: true
|
83
|
+
Exclude:
|
84
|
+
- '**/spec/**/*'
|
85
|
+
- '**/tasks/**/*.rake'
|
86
|
+
- '**/db/fixtures/**/*'
|
87
|
+
|
88
|
+
Discourse/Plugins/UseRequireRelative:
|
89
|
+
Enabled: true
|
90
|
+
|
91
|
+
Discourse/Plugins/NoMonkeyPatching:
|
92
|
+
Enabled: true
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Discourse
|
6
|
+
# When fabricating a record without custom attributes, we can use the
|
7
|
+
# fabricator shorthand as long as the identifier matches the fabricator
|
8
|
+
# name.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# fab!(:user) { Fabricate(:user) }
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# fab!(:user)
|
17
|
+
#
|
18
|
+
# When using custom attributes or the identifier doesn't match, the
|
19
|
+
# shorthand can't be used.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# fab!(:user) { Fabricate(:user, trust_level: TrustLevel[0]) }
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# fab!(:another_user) { Fabricate(:user) }
|
28
|
+
class FabricatorShorthand < Base
|
29
|
+
def_node_matcher :offending_fabricator?, <<-MATCHER
|
30
|
+
(block
|
31
|
+
(send nil? :fab!
|
32
|
+
(sym $_identifier))
|
33
|
+
(args)
|
34
|
+
(send nil? :Fabricate
|
35
|
+
(sym $_identifier)))
|
36
|
+
MATCHER
|
37
|
+
|
38
|
+
def on_block(node)
|
39
|
+
offending_fabricator?(node) do |identifier|
|
40
|
+
add_offense(node, message: message(identifier))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def message(identifier)
|
47
|
+
"Use the fabricator shorthand: `fab!(:#{identifier})`"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Discourse
|
6
|
+
module Plugins
|
7
|
+
# Plugin controllers must call `requires_plugin` to prevent routes from
|
8
|
+
# being accessible when the plugin is disabled.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
# # bad
|
12
|
+
# class MyController
|
13
|
+
# def my_action
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# class MyController
|
19
|
+
# requires_plugin PLUGIN_NAME
|
20
|
+
# def my_action
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
class CallRequiresPlugin < Base
|
25
|
+
MSG =
|
26
|
+
"Use `requires_plugin` in controllers to prevent routes from being accessible when plugin is disabled."
|
27
|
+
|
28
|
+
def_node_matcher :requires_plugin_present?, <<~MATCHER
|
29
|
+
(class _ _
|
30
|
+
{
|
31
|
+
(begin <(send nil? :requires_plugin _) ...>)
|
32
|
+
<(send nil? :requires_plugin _) ...>
|
33
|
+
}
|
34
|
+
)
|
35
|
+
MATCHER
|
36
|
+
|
37
|
+
def on_class(node)
|
38
|
+
return if requires_plugin_present?(node)
|
39
|
+
return if requires_plugin_present_in_parent_classes(node)
|
40
|
+
add_offense(node, message: MSG)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def requires_plugin_present_in_parent_classes(node)
|
46
|
+
return unless processed_source.path
|
47
|
+
controller_path =
|
48
|
+
base_controller_path(node.parent_class&.const_name.to_s)
|
49
|
+
return unless controller_path
|
50
|
+
Commissioner
|
51
|
+
.new([self.class.new(config, @options)])
|
52
|
+
.investigate(parse(controller_path.read, controller_path.to_s))
|
53
|
+
.offenses
|
54
|
+
.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
def base_controller_path(base_class)
|
58
|
+
return if base_class.blank?
|
59
|
+
base_path = "#{base_class.underscore}.rb"
|
60
|
+
path = Pathname.new("#{processed_source.path}/../").cleanpath
|
61
|
+
until path.root?
|
62
|
+
controller_path = path.join(base_path)
|
63
|
+
return controller_path if controller_path.exist?
|
64
|
+
path = path.join("..").cleanpath
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Discourse
|
6
|
+
module Plugins
|
7
|
+
# Constants must be defined inside the plugin namespace (module or class).
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# MY_CONSTANT = :value
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# module MyPlugin
|
15
|
+
# MY_CONSTANT = :value
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
class NamespaceConstants < Base
|
19
|
+
MSG = "Don’t define constants outside a class or a module."
|
20
|
+
|
21
|
+
def on_casgn(node)
|
22
|
+
return if inside_namespace?(node)
|
23
|
+
add_offense(node, message: MSG)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def inside_namespace?(node)
|
29
|
+
node.each_ancestor.detect { _1.class_type? || _1.module_type? }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Discourse
|
6
|
+
module Plugins
|
7
|
+
# Methods must be defined inside the plugin namespace (module or class).
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# def my_method
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# module MyPlugin
|
16
|
+
# def my_method
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
class NamespaceMethods < Base
|
21
|
+
MSG = "Don’t define methods outside a class or a module."
|
22
|
+
|
23
|
+
def on_def(node)
|
24
|
+
return if inside_namespace?(node)
|
25
|
+
add_offense(node, message: MSG)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def inside_namespace?(node)
|
31
|
+
node.each_ancestor.detect { _1.class_type? || _1.module_type? }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Discourse
|
6
|
+
module Plugins
|
7
|
+
# Don’t monkey-patch classes directly in `plugin.rb`. Instead, define
|
8
|
+
# additional methods in a dedicated mixin (an ActiveSupport concern for
|
9
|
+
# example) and use `prepend` (this allows calling `super` from the mixin).
|
10
|
+
#
|
11
|
+
# If you’re just adding new methods to an existing serializer, then use
|
12
|
+
# `add_to_serializer` instead.
|
13
|
+
#
|
14
|
+
# @example generic monkey-patching
|
15
|
+
# # bad
|
16
|
+
# ::Topic.class_eval do
|
17
|
+
# has_many :new_items
|
18
|
+
#
|
19
|
+
# def new_method
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# module MyPlugin::TopicExtension
|
25
|
+
# extend ActiveSupport::Concern
|
26
|
+
#
|
27
|
+
# prepended do
|
28
|
+
# has_many :new_items
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def new_method
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# reloadable_patch { ::Topic.prepend(MyPlugin::TopicExtension) }
|
36
|
+
#
|
37
|
+
# @example for serializers
|
38
|
+
# # bad
|
39
|
+
# UserSerializer.class_eval do
|
40
|
+
# def new_method
|
41
|
+
# do_processing
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# # good
|
46
|
+
# add_to_serializer(:user, :new_method) { do_processing }
|
47
|
+
#
|
48
|
+
class NoMonkeyPatching < Base
|
49
|
+
MSG =
|
50
|
+
"Don’t reopen existing classes. Instead, create a mixin and use `prepend`."
|
51
|
+
MSG_CLASS_EVAL =
|
52
|
+
"Don’t call `class_eval`. Instead, create a mixin and use `prepend`."
|
53
|
+
MSG_CLASS_EVAL_SERIALIZERS =
|
54
|
+
"Don’t call `class_eval` on a serializer. If you’re adding new methods, use `add_to_serializer`. Otherwise, create a mixin and use `prepend`."
|
55
|
+
MSG_SERIALIZERS =
|
56
|
+
"Don’t reopen serializers. Instead, use `add_to_serializer`."
|
57
|
+
RESTRICT_ON_SEND = [:class_eval].freeze
|
58
|
+
|
59
|
+
def_node_matcher :existing_class?, <<~MATCHER
|
60
|
+
(class (const (cbase) _) ...)
|
61
|
+
MATCHER
|
62
|
+
|
63
|
+
def_node_matcher :serializer?, <<~MATCHER
|
64
|
+
({class send} (const _ /Serializer$/) ...)
|
65
|
+
MATCHER
|
66
|
+
|
67
|
+
def on_send(node)
|
68
|
+
if serializer?(node)
|
69
|
+
return add_offense(node, message: MSG_CLASS_EVAL_SERIALIZERS)
|
70
|
+
end
|
71
|
+
add_offense(node, message: MSG_CLASS_EVAL)
|
72
|
+
end
|
73
|
+
|
74
|
+
def on_class(node)
|
75
|
+
return unless in_plugin_rb_file?
|
76
|
+
return unless existing_class?(node)
|
77
|
+
if serializer?(node)
|
78
|
+
return add_offense(node, message: MSG_SERIALIZERS)
|
79
|
+
end
|
80
|
+
add_offense(node, message: MSG)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def in_plugin_rb_file?
|
86
|
+
processed_source.path.split("/").last == "plugin.rb"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -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
|
data/lib/rubocop-discourse.rb
CHANGED
data/rubocop-core.yml
CHANGED
data/rubocop-discourse.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "rubocop-discourse"
|
5
|
-
s.version = "3.
|
5
|
+
s.version = "3.7.0"
|
6
6
|
s.summary = "Custom rubocop cops used by Discourse"
|
7
7
|
s.authors = ["Discourse Team"]
|
8
8
|
s.license = "MIT"
|
@@ -11,8 +11,11 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.files = `git ls-files`.split($/)
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
|
14
|
+
s.add_runtime_dependency "activesupport", ">= 6.1"
|
14
15
|
s.add_runtime_dependency "rubocop", ">= 1.59.0"
|
15
16
|
s.add_runtime_dependency "rubocop-rspec", ">= 2.25.0"
|
17
|
+
s.add_runtime_dependency "rubocop-factory_bot", ">= 2.0.0"
|
18
|
+
s.add_runtime_dependency "rubocop-capybara", ">= 2.0.0"
|
16
19
|
|
17
20
|
s.add_development_dependency "rake", "~> 13.1.0"
|
18
21
|
s.add_development_dependency "rspec", "~> 3.12.0"
|
data/rubocop-rspec.yml
CHANGED
@@ -223,23 +223,8 @@ RSpec/VoidExpect:
|
|
223
223
|
RSpec/Yield:
|
224
224
|
Enabled: true
|
225
225
|
|
226
|
-
Capybara/CurrentPathExpectation:
|
227
|
-
Enabled: true
|
228
|
-
|
229
226
|
RSpec/Capybara/FeatureMethods:
|
230
227
|
Enabled: true
|
231
228
|
|
232
|
-
Capybara/VisibilityMatcher:
|
233
|
-
Enabled: true
|
234
|
-
|
235
|
-
FactoryBot/AttributeDefinedStatically:
|
236
|
-
Enabled: true
|
237
|
-
|
238
|
-
FactoryBot/CreateList:
|
239
|
-
Enabled: true
|
240
|
-
|
241
|
-
FactoryBot/FactoryClassName:
|
242
|
-
Enabled: true
|
243
|
-
|
244
229
|
RSpec/Rails/HttpStatus:
|
245
230
|
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,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
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class InheritFromOutsideController < MyPlugin::ApplicationController
|
4
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/CallRequiresPlugin: Use `requires_plugin` in controllers to prevent routes from being accessible when plugin is disabled.
|
5
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe RuboCop::Cop::Discourse::FabricatorShorthand, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
it "registers an offense when not using the fabricator shorthand" do
|
11
|
+
expect_offense(<<~RUBY)
|
12
|
+
RSpec.describe "Foo" do
|
13
|
+
fab!(:foo) { Fabricate(:foo) }
|
14
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/FabricatorShorthand: Use the fabricator shorthand: `fab!(:foo)`
|
15
|
+
end
|
16
|
+
RUBY
|
17
|
+
end
|
18
|
+
|
19
|
+
it "does not register an offense when the fabricator has attributes" do
|
20
|
+
expect_no_offenses(<<~RUBY)
|
21
|
+
RSpec.describe "Foo" do
|
22
|
+
fab!(:foo) { Fabricate(:foo, bar: 1) }
|
23
|
+
end
|
24
|
+
RUBY
|
25
|
+
end
|
26
|
+
|
27
|
+
it "does not register an offense when the identifier doesn't match" do
|
28
|
+
expect_no_offenses(<<~RUBY)
|
29
|
+
RSpec.describe "Foo" do
|
30
|
+
fab!(:bar) { Fabricate(:foo) }
|
31
|
+
end
|
32
|
+
RUBY
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RuboCop::Cop::Discourse::Plugins::CallRequiresPlugin, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
context "when `requires_plugin` is missing" do
|
11
|
+
it "registers an offense" do
|
12
|
+
expect_offense(<<~RUBY)
|
13
|
+
class MyController < ApplicationController
|
14
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/CallRequiresPlugin: Use `requires_plugin` in controllers to prevent routes from being accessible when plugin is disabled.
|
15
|
+
requires_login
|
16
|
+
end
|
17
|
+
RUBY
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when `requires_plugin` is not missing" do
|
22
|
+
it "does not register an offense" do
|
23
|
+
expect_no_offenses(<<~RUBY)
|
24
|
+
class MyController
|
25
|
+
requires_plugin MyPlugin::PLUGIN_NAME
|
26
|
+
requires_login
|
27
|
+
end
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when inheriting" do
|
33
|
+
let(:controllers_path) do
|
34
|
+
Pathname.new("#{__dir__}/../../../../fixtures/controllers").cleanpath
|
35
|
+
end
|
36
|
+
|
37
|
+
before do
|
38
|
+
# As we’re providing real files, we need to get rid of the default config
|
39
|
+
# restricting the cop to `app/controllers/*`
|
40
|
+
configuration.for_cop(cop).delete("Include")
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when `requires_plugin` is called in a parent controller" do
|
44
|
+
let(:good_controller) { controllers_path.join("good_controller.rb") }
|
45
|
+
|
46
|
+
it "does not register an offense" do
|
47
|
+
expect_no_offenses(good_controller.read, good_controller.to_s)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when `requires_plugin` is not called in a parent controller" do
|
52
|
+
let(:bad_controller) { controllers_path.join("bad_controller.rb") }
|
53
|
+
|
54
|
+
it "registers an offense" do
|
55
|
+
expect_offense(bad_controller.read, bad_controller.to_s)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when parent controller can’t be located" do
|
60
|
+
context "when parent controller is namespaced" do
|
61
|
+
let(:controller) do
|
62
|
+
controllers_path.join("namespaced_parent_controller.rb")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "registers an offense" do
|
66
|
+
expect_offense(controller.read, controller.to_s)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when parent controller is not namespaced" do
|
71
|
+
let(:controller) do
|
72
|
+
controllers_path.join("inherit_from_outside_controller.rb")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "registers an offense" do
|
76
|
+
expect_offense(controller.read, controller.to_s)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RuboCop::Cop::Discourse::Plugins::NamespaceConstants, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
context "when defining a constant outside any namespace" do
|
11
|
+
it "registers an offense" do
|
12
|
+
expect_offense(<<~RUBY)
|
13
|
+
MY_CONSTANT = "my_value"
|
14
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/NamespaceConstants: Don’t define constants outside a class or a module.
|
15
|
+
|
16
|
+
class MyClass
|
17
|
+
MY_CONSTANT = "my_value"
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when defining a constant inside a class" do
|
24
|
+
it "does not register an offense" do
|
25
|
+
expect_no_offenses(<<~RUBY)
|
26
|
+
class MyClass
|
27
|
+
MY_CONSTANT = "my_value"
|
28
|
+
end
|
29
|
+
RUBY
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when defining a constant inside a module" do
|
34
|
+
it "does not register an offense" do
|
35
|
+
expect_no_offenses(<<~RUBY)
|
36
|
+
module MyModule
|
37
|
+
MY_CONSTANT = "my_value"
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RuboCop::Cop::Discourse::Plugins::NamespaceMethods, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
context "when defining a method outside any namespace" do
|
11
|
+
it "registers an offense" do
|
12
|
+
expect_offense(<<~RUBY)
|
13
|
+
def my_method
|
14
|
+
^^^^^^^^^^^^^ Discourse/Plugins/NamespaceMethods: Don’t define methods outside a class or a module.
|
15
|
+
"my_value"
|
16
|
+
end
|
17
|
+
|
18
|
+
class MyClass
|
19
|
+
def my_method
|
20
|
+
"my_method"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when defining a method inside a class" do
|
28
|
+
context "when defining an instance method" do
|
29
|
+
it "does not register an offense" do
|
30
|
+
expect_no_offenses(<<~RUBY)
|
31
|
+
class MyClass
|
32
|
+
def my_method
|
33
|
+
"my_value"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
RUBY
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when defining a class method" do
|
41
|
+
it "does not register an offense" do
|
42
|
+
expect_no_offenses(<<~RUBY)
|
43
|
+
class MyClass
|
44
|
+
class << self
|
45
|
+
def my_method
|
46
|
+
"my_value"
|
47
|
+
end
|
48
|
+
|
49
|
+
def another_method
|
50
|
+
"plop"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
RUBY
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when defining a method inside a module" do
|
60
|
+
context "when defining an instance method" do
|
61
|
+
it "does not register an offense" do
|
62
|
+
expect_no_offenses(<<~RUBY)
|
63
|
+
module MyModule
|
64
|
+
def my_method
|
65
|
+
"my_value"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
RUBY
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when defining a class method" do
|
73
|
+
it "does not register an offense" do
|
74
|
+
expect_no_offenses(<<~RUBY)
|
75
|
+
module MyModule
|
76
|
+
class << self
|
77
|
+
def my_method
|
78
|
+
"my_value"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
RUBY
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RuboCop::Cop::Discourse::Plugins::NoMonkeyPatching, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
context "when outside `plugin.rb`" do
|
11
|
+
it "does not register an offense" do
|
12
|
+
expect_no_offenses(<<~RUBY, "my_class.rb")
|
13
|
+
class ::MyClass
|
14
|
+
def my_method
|
15
|
+
"my_value"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class AnotherClass
|
20
|
+
def my_method
|
21
|
+
"my_value"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
RUBY
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when inside `plugin.rb`" do
|
29
|
+
context "when opening an existing class" do
|
30
|
+
it "registers an offense" do
|
31
|
+
expect_offense(<<~RUBY, "plugin.rb")
|
32
|
+
after_initialize do
|
33
|
+
module MyPlugin
|
34
|
+
class Engine < Rails::Engine
|
35
|
+
isolate_namespace MyPlugin
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class ::Topic
|
40
|
+
^^^^^^^^^^^^^ Discourse/Plugins/NoMonkeyPatching: Don’t reopen existing classes. [...]
|
41
|
+
def self.new_method
|
42
|
+
:new_value
|
43
|
+
end
|
44
|
+
|
45
|
+
def my_new_method
|
46
|
+
"my_new_value"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when opening an existing serializer" do
|
55
|
+
it "registers an offense" do
|
56
|
+
expect_offense(<<~RUBY, "plugin.rb")
|
57
|
+
class ::TopicSerializer
|
58
|
+
^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/NoMonkeyPatching: Don’t reopen serializers. [...]
|
59
|
+
def new_attribute
|
60
|
+
"my_attribute"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
RUBY
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when calling `.class_eval` on a class" do
|
68
|
+
it "registers an offense" do
|
69
|
+
expect_offense(<<~RUBY)
|
70
|
+
User.class_eval do
|
71
|
+
^^^^^^^^^^^^^^^ Discourse/Plugins/NoMonkeyPatching: Don’t call `class_eval`. [...]
|
72
|
+
def a_new_method
|
73
|
+
:new_value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
RUBY
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when calling `.class_eval` on a serializer" do
|
81
|
+
it "registers an offense" do
|
82
|
+
expect_offense(<<~RUBY)
|
83
|
+
UserSerializer.class_eval do
|
84
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/NoMonkeyPatching: Don’t call `class_eval` on a serializer. [...]
|
85
|
+
def a_new_method
|
86
|
+
:new_value
|
87
|
+
end
|
88
|
+
end
|
89
|
+
RUBY
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RuboCop::Cop::Discourse::Plugins::UsePluginInstanceOn, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
context "when outside `plugin.rb`" do
|
11
|
+
context "when `DiscourseEvent.on` is called" do
|
12
|
+
it "registers an offense" do
|
13
|
+
expect_offense(<<~RUBY, "another_file.rb")
|
14
|
+
DiscourseEvent.on(:topic_status_updated) { do_something }
|
15
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/UsePluginInstanceOn: Don’t call `DiscourseEvent.on` outside `plugin.rb`.
|
16
|
+
RUBY
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when inside `plugin.rb`" do
|
22
|
+
context "when `DiscourseEvent.on` is called" do
|
23
|
+
it "registers an offense" do
|
24
|
+
expect_offense(<<~RUBY, "plugin.rb")
|
25
|
+
DiscourseEvent.on(:topic_status_updated) { do_something }
|
26
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/UsePluginInstanceOn: Use `on` instead of `DiscourseEvent.on` [...]
|
27
|
+
RUBY
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when `on` is called" do
|
32
|
+
it "does not register an offense" do
|
33
|
+
expect_no_offenses(<<~RUBY, "plugin.rb")
|
34
|
+
on(:topic_status_updated) { do_something }
|
35
|
+
RUBY
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe RuboCop::Cop::Discourse::Plugins::UseRequireRelative, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
let(:config) { RuboCop::Config.new }
|
9
|
+
|
10
|
+
context "when using `load`" do
|
11
|
+
it "registers an offense" do
|
12
|
+
expect_offense(<<~RUBY)
|
13
|
+
load File.expand_path("../app/jobs/onceoff/voting_ensure_consistency.rb", __FILE__)
|
14
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/Plugins/UseRequireRelative: Use `require_relative` instead of `load`.
|
15
|
+
RUBY
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when using `require_relative`" do
|
20
|
+
it "does not register an offense" do
|
21
|
+
expect_no_offenses(<<~RUBY)
|
22
|
+
require_relative "app/controllers/encrypt_controller.rb"
|
23
|
+
RUBY
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/stree-compat.yml
CHANGED
@@ -3,10 +3,13 @@ require:
|
|
3
3
|
|
4
4
|
inherit_from:
|
5
5
|
- ./rubocop-core.yml
|
6
|
+
- ./rubocop-capybara.yml
|
7
|
+
- ./rubocop-factory_bot.yml
|
6
8
|
- ./rubocop-rspec.yml
|
7
9
|
|
8
10
|
AllCops:
|
9
11
|
TargetRubyVersion: 3.2
|
12
|
+
SuggestExtensions: false
|
10
13
|
DisabledByDefault: true
|
11
14
|
Exclude:
|
12
15
|
- 'db/schema.rb'
|
@@ -19,3 +22,8 @@ AllCops:
|
|
19
22
|
|
20
23
|
Discourse:
|
21
24
|
Enabled: true
|
25
|
+
|
26
|
+
Discourse/FabricatorShorthand:
|
27
|
+
Enabled: true
|
28
|
+
Include:
|
29
|
+
- 'spec/**/*_spec.rb'
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-discourse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Discourse Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '6.1'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rubocop
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +52,34 @@ dependencies:
|
|
38
52
|
- - ">="
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: 2.25.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop-factory_bot
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.0.0
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.0.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-capybara
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.0.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.0.0
|
41
83
|
- !ruby/object:Gem::Dependency
|
42
84
|
name: rake
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,6 +124,7 @@ files:
|
|
82
124
|
- config/default.yml
|
83
125
|
- default.yml
|
84
126
|
- lib/rubocop-discourse.rb
|
127
|
+
- lib/rubocop/cop/discourse/fabricator_shorthand.rb
|
85
128
|
- lib/rubocop/cop/discourse/no_add_reference_active_record_migrations.rb
|
86
129
|
- lib/rubocop/cop/discourse/no_chdir.rb
|
87
130
|
- lib/rubocop/cop/discourse/no_direct_multisite_manipulation.rb
|
@@ -93,19 +136,41 @@ files:
|
|
93
136
|
- lib/rubocop/cop/discourse/no_time_new_without_args.rb
|
94
137
|
- lib/rubocop/cop/discourse/no_uri_escape_encode.rb
|
95
138
|
- lib/rubocop/cop/discourse/only_top_level_multisite_specs.rb
|
139
|
+
- lib/rubocop/cop/discourse/plugins/call_requires_plugin.rb
|
140
|
+
- lib/rubocop/cop/discourse/plugins/namespace_constants.rb
|
141
|
+
- lib/rubocop/cop/discourse/plugins/namespace_methods.rb
|
142
|
+
- lib/rubocop/cop/discourse/plugins/no_monkey_patching.rb
|
143
|
+
- lib/rubocop/cop/discourse/plugins/use_plugin_instance_on.rb
|
144
|
+
- lib/rubocop/cop/discourse/plugins/use_require_relative.rb
|
96
145
|
- lib/rubocop/cop/discourse/time_eq_matcher.rb
|
97
146
|
- lib/rubocop/cop/discourse_cops.rb
|
98
147
|
- lib/rubocop/discourse.rb
|
99
148
|
- lib/rubocop/discourse/inject.rb
|
149
|
+
- rubocop-capybara.yml
|
100
150
|
- rubocop-core.yml
|
101
151
|
- rubocop-discourse.gemspec
|
152
|
+
- rubocop-factory_bot.yml
|
102
153
|
- rubocop-layout.yml
|
103
154
|
- rubocop-rspec.yml
|
155
|
+
- spec/fixtures/controllers/bad_controller.rb
|
156
|
+
- spec/fixtures/controllers/base_controller.rb
|
157
|
+
- spec/fixtures/controllers/good_controller.rb
|
158
|
+
- spec/fixtures/controllers/inherit_from_outside_controller.rb
|
159
|
+
- spec/fixtures/controllers/namespaced_parent_controller.rb
|
160
|
+
- spec/fixtures/controllers/no_requires_plugin_controller.rb
|
161
|
+
- spec/fixtures/controllers/requires_plugin_controller.rb
|
162
|
+
- spec/lib/rubocop/cop/fabricator_shorthand_spec.rb
|
104
163
|
- spec/lib/rubocop/cop/no_add_reference_active_record_migrations_spec.rb
|
105
164
|
- spec/lib/rubocop/cop/no_mixing_multisite_and_standard_specs_spec.rb
|
106
165
|
- spec/lib/rubocop/cop/no_mocking_jobs_enqueue_spec.rb
|
107
166
|
- spec/lib/rubocop/cop/no_reset_column_information_migrations_spec.rb
|
108
167
|
- spec/lib/rubocop/cop/only_top_level_multisite_specs_spec.rb
|
168
|
+
- spec/lib/rubocop/cop/plugins/call_requires_plugin_spec.rb
|
169
|
+
- spec/lib/rubocop/cop/plugins/namespace_constants_spec.rb
|
170
|
+
- spec/lib/rubocop/cop/plugins/namespace_methods_spec.rb
|
171
|
+
- spec/lib/rubocop/cop/plugins/no_monkey_patching_spec.rb
|
172
|
+
- spec/lib/rubocop/cop/plugins/use_plugin_instance_on_spec.rb
|
173
|
+
- spec/lib/rubocop/cop/plugins/use_require_relative_spec.rb
|
109
174
|
- spec/lib/rubocop/cop/time_eq_matcher_spec.rb
|
110
175
|
- spec/spec_helper.rb
|
111
176
|
- stree-compat.yml
|