rubocop-obsession 0.1.14 → 0.1.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37b348efda2df448308744549f3a30181b44839d436a5219356579ef319ce8a4
4
- data.tar.gz: 3ad138c089db20056117e20650f844de403253b147a35c2286eebbaef7c06faf
3
+ metadata.gz: be68e2beb303a311848858498767c76c03cc98031d8716bc27a702c3e2d0bb01
4
+ data.tar.gz: 0e867c196f843e6c206794e9938e0e88a779b8b231f51b43f4aeed02d6331efa
5
5
  SHA512:
6
- metadata.gz: ee4ef4d270d3c6a33592370ada26298c81a8a1319fde90ae047bec81c87fe1732ed20a5bacc8ec969bcb52b9e2adfa2f440a28e7454f65f370bb225b91b75143
7
- data.tar.gz: 378bf2513dedcb169400b5d0028775a3d330b576f5c520e3b4ff1e9ca27a658f8c15a7ab5ef3bc282e950527559d7d37b93eeba9c842dd77a4b667273d9ef170
6
+ metadata.gz: dfa035279001455509c1a4ee73d1aeae9e418733471691270c0c9627371f3ebd24415db377985ca6ff1f583e9843a65712be9ff9d640cc60643b2197b12f3e51
7
+ data.tar.gz: 90a7ed2c98377e3367ac0a177629c8e83a19b56cc294ddbadd260a3d67ce941a95b26f626401904078753822a00ae17babbb95f1c88bd6c128646917423c5908
data/README.md CHANGED
@@ -9,8 +9,8 @@ There are some lower-level cops as well.
9
9
  Use the provided cops as is, or as inspiration to build custom cops aligned
10
10
  with your project's best practices.
11
11
 
12
- Does your project have any cool custom cops that you think others might benefit
13
- from? Then please open a PR!
12
+ Does your project have any cool custom cops that others might benefit from?
13
+ Then please open a PR!
14
14
 
15
15
  ## Installation
16
16
 
data/config/default.yml CHANGED
@@ -1,5 +1,9 @@
1
1
  Obsession/MethodOrder:
2
2
  Enabled: true
3
+ EnforcedStyle: drill_down
4
+ SupportedStyles:
5
+ - drill_down
6
+ - step_down
3
7
  Obsession/NoBreakOrNext:
4
8
  Enabled: false
5
9
  Exclude:
@@ -10,7 +10,6 @@ module RuboCop
10
10
  # and actions are best described with verbs.
11
11
  #
12
12
  # @example
13
- #
14
13
  # # bad
15
14
  # module Mutations
16
15
  # class Event < Base
@@ -6,9 +6,8 @@ module RuboCop
6
6
  # This cop checks for private/protected methods that are not ordered
7
7
  # correctly. It supports autocorrect.
8
8
  #
9
- # Code should read from top to bottom: methods should be defined in the
10
- # same order as the order when they are first mentioned.
11
- # Private/protected methods should follow that rule.
9
+ # Code should read from top to bottom. Private/protected methods should
10
+ # follow that rule.
12
11
  #
13
12
  # Note 1: public methods do not have to follow that rule, and can be
14
13
  # defined in any order the developer wants, like by order of importance.
@@ -20,44 +19,121 @@ module RuboCop
20
19
  # Note 2: method order cannot be computed for methods called by `send`,
21
20
  # metaprogramming, private methods called by superclasses or modules,
22
21
  # etc. This cop's suggestions and autocorrections may be slightly off for
23
- # these kinds of edge cases.
22
+ # these cases.
24
23
  #
25
24
  # Note 3: for simplicity, protected methods do not have to follow that
26
25
  # rule if there are both a protected section and a private section.
27
26
  #
28
- # Note 4: for more information on this style of method ordering, see
29
- # Robert C. Martin's "Clean Code" book > "Chapter 3: Functions" > "One
30
- # level of abstraction per function" > "Reading Code from Top to Bottom:
31
- # The Stepdown Rule" chapter.
27
+ # @example EnforcedStyle: drill_down (default)
28
+ # In this style, methods should be defined in the same order as the
29
+ # order when they are first mentioned. This means that a called method
30
+ # is defined below the caller method as immediately as possible. In
31
+ # other words, you go to the bottom of the method call tree before
32
+ # going back up. See the second example.
32
33
  #
33
- # @example
34
+ # This style is similar to the code example provided in the "Reading
35
+ # Code from Top to Bottom: The Stepdown Rule" chapter from Robert C.
36
+ # Martin's "Clean Code" book, but diverges from it in that it drills
37
+ # down to the bottom of the call tree as much as possible.
34
38
  #
35
39
  # # bad
36
- # def perform
37
- # return if method_a?
38
- # method_b
39
- # method_c
40
+ # class Foo
41
+ # def perform
42
+ # return if method_a?
43
+ # method_b
44
+ # method_c
45
+ # end
46
+ #
47
+ # private
48
+ #
49
+ # def method_c; ...; end
50
+ # def method_b; ...; end
51
+ # def method_a?; ...; end
52
+ # end
53
+ #
54
+ # # good
55
+ # class Foo
56
+ # def perform
57
+ # return if method_a?
58
+ # method_b
59
+ # method_c
60
+ # end
61
+ #
62
+ # private
63
+ #
64
+ # def method_a?; ...; end
65
+ # def method_b; ...; end
66
+ # def method_c; ...; end
40
67
  # end
41
68
  #
42
- # private
69
+ # # bad
70
+ # class Foo
71
+ # def perform
72
+ # method_a
73
+ # method_b
74
+ # end
75
+ #
76
+ # private
43
77
  #
44
- # def method_c; ...; end
45
- # def method_b; ...; end
46
- # def method_a?; ...; end
78
+ # def method_a; method_c; end
79
+ # def method_b; method_c; end
80
+ # def method_c; ...; end
81
+ # end
47
82
  #
48
83
  # # good
49
- # def perform
50
- # return if method_a?
51
- # method_b
52
- # method_c
84
+ # class Foo
85
+ # def perform
86
+ # method_a
87
+ # method_b
88
+ # end
89
+ #
90
+ # private
91
+ #
92
+ # def method_a; method_c; end
93
+ # def method_c; ...; end
94
+ # def method_b; method_c; end
53
95
  # end
54
96
  #
55
- # private
97
+ # @example EnforcedStyle: step_down
98
+ # In this style, common called methods (which tend to have a lower
99
+ # level of abstraction) are defined after the group of methods that
100
+ # calls them (these caller methods tend to have a higher level of
101
+ # abstraction). The idea is to gradually descend one level of
102
+ # abstraction at a time.
103
+ #
104
+ # This style adheres more strictly to the code example provided in the
105
+ # "Reading Code from Top to Bottom: The Stepdown Rule" chapter from
106
+ # Robert C. Martin's "Clean Code" book.
56
107
  #
57
- # def method_a?; ...; end
58
- # def method_b; ...; end
59
- # def method_c; ...; end
108
+ # # bad
109
+ # class Foo
110
+ # def perform
111
+ # method_a
112
+ # method_b
113
+ # end
114
+ #
115
+ # private
116
+ #
117
+ # def method_a; method_c; end
118
+ # def method_c; ...; end
119
+ # def method_b; method_c; end
120
+ # end
121
+ #
122
+ # # good
123
+ # class Foo
124
+ # def perform
125
+ # method_a
126
+ # method_b
127
+ # end
128
+ #
129
+ # private
130
+ #
131
+ # def method_a; method_c; end
132
+ # def method_b; method_c; end
133
+ # def method_c; ...; end
134
+ # end
60
135
  class MethodOrder < Base
136
+ include ConfigurableEnforcedStyle
61
137
  include Helpers
62
138
  include CommentsHelp
63
139
  include VisibilityHelp
@@ -183,10 +259,14 @@ module RuboCop
183
259
  def ordered_private_methods(node)
184
260
  ast_node = node.value
185
261
  method_name = should_ignore?(ast_node) ? nil : ast_node.method_name
186
-
187
262
  next_names = node.children.flat_map { |child| ordered_private_methods(child) }
188
263
 
189
- ([method_name] + next_names).compact.uniq
264
+ common_methods =
265
+ drill_down_style? ? [] : next_names.tally.select { |_, size| size > 1 }.keys
266
+
267
+ unique_methods = next_names - common_methods
268
+
269
+ ([method_name] + unique_methods + common_methods).compact.uniq
190
270
  end
191
271
 
192
272
  def should_ignore?(ast_node)
@@ -194,6 +274,10 @@ module RuboCop
194
274
  !@called_methods.include?(ast_node)
195
275
  end
196
276
 
277
+ def drill_down_style?
278
+ style == :drill_down
279
+ end
280
+
197
281
  def build_private_methods
198
282
  @private_methods = @methods.keys.intersection(@ordered_private_methods)
199
283
  end
@@ -15,7 +15,6 @@ module RuboCop
15
15
  # `loop` + `break` into a `while`.
16
16
  #
17
17
  # @example
18
- #
19
18
  # # bad
20
19
  # github_teams.each do |github_team|
21
20
  # next if github_team['size'] == 0
@@ -11,7 +11,6 @@ module RuboCop
11
11
  # could be: initialization, action, and result.
12
12
  #
13
13
  # @example
14
- #
15
14
  # # bad
16
15
  # def set_seo_content
17
16
  # return if slug.blank?
@@ -13,7 +13,6 @@ module RuboCop
13
13
  # leaves the company, and never gets a chance to tackle them.
14
14
  #
15
15
  # @example
16
- #
17
16
  # # bad
18
17
  # # TODO: remove this method when we ship the new signup flow
19
18
  # def my_method
@@ -9,7 +9,6 @@ module RuboCop
9
9
  # One method per callback definition makes the definition extra clear.
10
10
  #
11
11
  # @example
12
- #
13
12
  # # bad
14
13
  # after_create :notify_followers, :send_stats
15
14
  #
@@ -16,7 +16,6 @@ module RuboCop
16
16
  # defining the field.
17
17
  #
18
18
  # @example
19
- #
20
19
  # # bad
21
20
  # def change
22
21
  # add_column :languages, :items, :jsonb
@@ -11,7 +11,6 @@ module RuboCop
11
11
  # declarations that you find in model code.
12
12
  #
13
13
  # @example
14
- #
15
14
  # # bad
16
15
  # def change
17
16
  # add_reference :blog_posts, :user
@@ -16,7 +16,6 @@ module RuboCop
16
16
  # custom validation callbacks.
17
17
  #
18
18
  # @example
19
- #
20
19
  # # bad
21
20
  # after_update_commit :crawl_rss, if: :rss_changed?
22
21
  #
@@ -11,7 +11,6 @@ module RuboCop
11
11
  # be private.
12
12
  #
13
13
  # @example
14
- #
15
14
  # # bad
16
15
  # before_action :load_blog_post
17
16
  #
@@ -15,7 +15,6 @@ module RuboCop
15
15
  # app down.
16
16
  #
17
17
  # @example
18
- #
19
18
  # # bad
20
19
  # class RemoveSourceUrlFromBlogPosts < ActiveRecord::Migration[8.0]
21
20
  # def change
@@ -11,7 +11,6 @@ module RuboCop
11
11
  # one action, and the best way to describe an action is with a verb.
12
12
  #
13
13
  # @example
14
- #
15
14
  # # bad
16
15
  # class Company
17
16
  # def perform
@@ -13,7 +13,6 @@ module RuboCop
13
13
  # interchangeable.
14
14
  #
15
15
  # @example
16
- #
17
16
  # # bad
18
17
  # class ImportCompany
19
18
  # def import
@@ -7,7 +7,6 @@ module RuboCop
7
7
  # This cop checks for `after_commit` declarations that could be shorter.
8
8
  #
9
9
  # @example
10
- #
11
10
  # # bad
12
11
  # after_commit :send_email, on: :create
13
12
  #
@@ -7,7 +7,6 @@ module RuboCop
7
7
  # This cop checks for `validate` declarations that could be shorter.
8
8
  #
9
9
  # @example
10
- #
11
10
  # # bad
12
11
  # validate :validate_url, on: %i(create update)
13
12
  #
@@ -9,7 +9,6 @@ module RuboCop
9
9
  # One field per `validates` makes the validation extra clear.
10
10
  #
11
11
  # @example
12
- #
13
12
  # # bad
14
13
  # validates :name, :status, presence: true
15
14
  #
@@ -7,7 +7,6 @@ module RuboCop
7
7
  # This cop checks for validation methods that do not start with `validate_`.
8
8
  #
9
9
  # @example
10
- #
11
10
  # # bad
12
11
  # validate :at_least_one_admin
13
12
  #
@@ -15,7 +15,6 @@ module RuboCop
15
15
  # corresponding Rails public method, e.g. #create, #save, etc.
16
16
  #
17
17
  # @example
18
- #
19
18
  # class Comment < ApplicationRecord
20
19
  # after_create_commit :notify_users
21
20
  #
@@ -7,7 +7,6 @@ if defined?(RuboCop::RSpec)
7
7
  # by `it` with no new line, to allow for this style of spec:
8
8
  #
9
9
  # @example
10
- #
11
10
  # describe Url do
12
11
  # describe '#domain' do
13
12
  # context do
@@ -15,7 +15,6 @@ module RuboCop
15
15
  # could be a sign that they should be broken into smaller methods.
16
16
  #
17
17
  # @example
18
- #
19
18
  # # bad
20
19
  # def set_seo_content
21
20
  # return if seo_content.present?
@@ -1,5 +1,5 @@
1
1
  module Rubocop
2
2
  module Obsession
3
- VERSION = '0.1.14'
3
+ VERSION = '0.1.15'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-obsession
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jerome Dalbert
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-02-04 00:00:00.000000000 Z
11
+ date: 2025-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport