nucop-cops 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 783eebd292d89fd9712f9f247249407e807afc0df09c20b5ed26bee92bab72fb
4
+ data.tar.gz: f12a4a355141d167e466415a2e8818fc4ca41aba64c17ec072507ac272d77d85
5
+ SHA512:
6
+ metadata.gz: 9427af1245874bc0c1504dff7d004c51db2c39ca03c57806c4de2596597abc5ed4e298022d42de75888407544ab272d4d6bc51dbcc4628c729b7d463a542c99d
7
+ data.tar.gz: 64620e5c1e287e7b38cadc2de0f709a777c338e1c369abcdabe07a104b06028cb99ad53c70b9c649df91eac22e74e73cd85f7f251683b1114c81f61a15d2e577
@@ -0,0 +1,40 @@
1
+ module Nucop
2
+ # This cop looks for usages of `FactoryGirl.create`, etc.
3
+ # See FactoryBotHelper::FACTORY_BOT_METHODS constant for a complete list.
4
+ #
5
+ # The factory methods listed are included everywhere, so referencing the constant should rarely be necessary.
6
+ #
7
+ # @example
8
+ #
9
+ # # bad
10
+ #
11
+ # job = FactoryGirl.create(:job, project: project)
12
+ # FactoryGirl.build(:project, code: "Super Project")
13
+ #
14
+ # # good
15
+ #
16
+ # job = create(:job, project: project)
17
+ # build(:project, code: "Super Project")
18
+ class ExplicitFactoryBotUsage < ::RuboCop::Cop::Base
19
+ extend RuboCop::Cop::AutoCorrector
20
+ include Helpers::FilePathHelper
21
+
22
+ MSG = "Do not explicitly use `%<constant>s` to build objects. The factory method `%<method>s` is globally available."
23
+
24
+ def_node_matcher :explicit_factory_bot_usage, <<~PATTERN
25
+ (send (const nil? {:FactoryGirl :FactoryBot}) {#{Helpers::FactoryBotHelper.factory_bot_methods_pattern}} ...)
26
+ PATTERN
27
+
28
+ def on_send(node)
29
+ explicit_factory_bot_usage(node) do
30
+ add_offense(node, message: format(MSG, constant: node.receiver.const_name, method: node.method_name)) do |corrector|
31
+ corrector.replace(node.source_range, node.source.sub(/(?:FactoryGirl|FactoryBot)[.]/, ""))
32
+ end
33
+ end
34
+ end
35
+
36
+ def relevant_file?(file)
37
+ acceptance_or_spec_file?(file) && super
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,31 @@
1
+ module Nucop
2
+ # This cop looks for core method overrides
3
+ #
4
+ # @example
5
+ #
6
+ # # bad
7
+ #
8
+ # def blank?
9
+ # # ...
10
+ # end
11
+ #
12
+ # # good
13
+ #
14
+ # def anything_other_than_blank?
15
+ # # ...
16
+ # end
17
+ #
18
+ class NoCoreMethodOverrides < ::RuboCop::Cop::Base
19
+ MSG = "Core method overridden".freeze
20
+
21
+ def_node_matcher :core_methods, <<~PATTERN
22
+ (def ${:present? :blank? :empty?} ...)
23
+ PATTERN
24
+
25
+ def on_def(node)
26
+ core_methods(node) do |method|
27
+ add_offense(node, message: format(MSG, method: method))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ module Nucop
2
+ # This cop looks for WIP specs
3
+ #
4
+ # @example
5
+ #
6
+ # # bad
7
+ #
8
+ # it "tests some stuff", :wip do
9
+ # # ...
10
+ # end
11
+ #
12
+ # # good
13
+ #
14
+ # it "tests some stuff" do
15
+ # # ...
16
+ # end
17
+ #
18
+ class NoWipSpecs < ::RuboCop::Cop::Base
19
+ MSG = "WIP spec found".freeze
20
+
21
+ def_node_matcher :wip_it_specs_present?, <<~PATTERN
22
+ (send nil? :it ... (sym :wip))
23
+ PATTERN
24
+
25
+ def_node_matcher :wip_describe_specs_present?, <<~PATTERN
26
+ (send nil? :describe ... (sym :wip))
27
+ PATTERN
28
+
29
+ def on_send(node)
30
+ return unless wip_it_specs_present?(node) || wip_describe_specs_present?(node)
31
+
32
+ add_offense(node)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ module Nucop
2
+ # This cop looks for usages of `ActiveSupport::OrderedHash`
3
+ #
4
+ # Hashes in Ruby (since 1.9) enumerate their keys in the order they are
5
+ # inserted:
6
+ #
7
+ # "Hashes enumerate their values in the order that the corresponding keys were inserted."
8
+ # http://ruby-doc.org/core-2.1.6/Hash.html
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ #
14
+ # hash = ActiveSupport::OrderedHash.new
15
+ #
16
+ # # good
17
+ #
18
+ # hash = {}
19
+ class OrderedHash < ::RuboCop::Cop::Base
20
+ extend RuboCop::Cop::AutoCorrector
21
+
22
+ MSG = "Ruby hashes after 1.9 enumerate keys in order of insertion"
23
+
24
+ def_node_matcher :ordered_hash_usage, <<~PATTERN
25
+ (send (const (const nil? :ActiveSupport) :OrderedHash) :new)
26
+ PATTERN
27
+
28
+ def on_send(node)
29
+ ordered_hash_usage(node) do
30
+ add_offense(node, message: MSG) do |corrector|
31
+ corrector.replace(node.source_range, "{}")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ module Nucop
2
+ # This cop checks that a symbol is used when using a Release Toggle name
3
+ #
4
+ # @example
5
+ #
6
+ # # bad
7
+ #
8
+ # release_toggle_enabled?("move_out_of_wip_autocomplete")
9
+ # release_toggle_enabled_for_any_site?("versioned_production_specification_ui")
10
+ # ReleaseToggles.enabled?("test_toggle", site_id: current_user.site_id)
11
+ # ReleaseToggles.disabled?("test_toggl"e, site_id: current_user.site_id)
12
+ # ReleaseToggles.enable("test_toggle", site_id: current_user.site_id)
13
+ # ReleaseToggles.disable!("test_toggle", site_id: current_user.site_id)
14
+ #
15
+ # # good
16
+ #
17
+ # release_toggle_enabled?(:move_out_of_wip_autocomplete)
18
+ #
19
+ class ReleaseTogglesUseSymbols < ::RuboCop::Cop::Base
20
+ extend RuboCop::Cop::AutoCorrector
21
+
22
+ MSG = "Use a symbol when referring to a Release Toggle's by name".freeze
23
+
24
+ def_node_matcher :test_helper?, <<~PATTERN
25
+ (send nil? {:release_toggle_enabled? :release_toggle_enabled_for_any_site?} (str _))
26
+ PATTERN
27
+
28
+ def_node_matcher :release_toggles_public_api_method?, <<~PATTERN
29
+ (send (const nil? :ReleaseToggles) {:enabled? :disabled? :enable :disable :enable! :disable!} (str _) ...)
30
+ PATTERN
31
+
32
+ def on_send(node)
33
+ test_helper?(node) { add_offense(node, message: MSG, location: node.children[2].loc.expression) }
34
+ release_toggles_public_api_method?(node) do
35
+ add_offense(node, message: MSG, location: node.children[2].loc.expression) do |corrector|
36
+ toggle_name = node.children[2].value
37
+
38
+ corrector.replace(node.children[2].source_range, ":#{toggle_name}")
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,37 @@
1
+ module Nucop
2
+ # This cop looks for defined methods in spec files that would shadow methods defined in FactoryBot::Syntax::Methods.
3
+ # See FactoryBotHelper::FACTORY_BOT_METHODS constant for a complete list.
4
+ #
5
+ # @example
6
+ #
7
+ # # bad
8
+ #
9
+ # def create(args)
10
+ # ...
11
+ # end
12
+ #
13
+ # # good
14
+ #
15
+ # def create_transfer_pallet(args)
16
+ # ...
17
+ # end
18
+ class ShadowingFactoryBotCreationMethods < ::RuboCop::Cop::Base
19
+ include Helpers::FilePathHelper
20
+
21
+ MSG = "Method `%<method>s` shadows a FactoryBot method. Please rename it to be more specific."
22
+
23
+ def_node_matcher :factory_bot_methods, <<~PATTERN
24
+ (def ${#{Helpers::FactoryBotHelper.factory_bot_methods_pattern}} ...)
25
+ PATTERN
26
+
27
+ def on_def(node)
28
+ factory_bot_methods(node) do |method|
29
+ add_offense(node, message: format(MSG, method: method))
30
+ end
31
+ end
32
+
33
+ def relevant_file?(file)
34
+ acceptance_or_spec_file?(file) && super
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ module Nucop
2
+ module Helpers
3
+ module FactoryBotHelper
4
+ module_function
5
+
6
+ FACTORY_BOT_METHODS = [
7
+ :build,
8
+ :build_list,
9
+ :build_pair,
10
+
11
+ :create,
12
+ :create_list,
13
+ :create_pair,
14
+
15
+ :build_stubbed,
16
+ :build_stubbed_list,
17
+ :build_stubbed_pair,
18
+
19
+ :attributes_for,
20
+ :attributes_for_list,
21
+ :attributes_for_pair
22
+ ]
23
+ private_constant :FACTORY_BOT_METHODS
24
+
25
+ def factory_bot_methods_pattern
26
+ FACTORY_BOT_METHODS.map(&:inspect).join(" ")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ module Nucop
2
+ module Helpers
3
+ module FilePathHelper
4
+ def acceptance_or_spec_file?(filepath)
5
+ Pathname.new(filepath).fnmatch?(File.join("**", "{spec,acceptance}", "**"), File::FNM_EXTGLOB)
6
+ end
7
+
8
+ def support_file?(filepath)
9
+ Pathname.new(filepath).fnmatch?(File.join("**", "support", "**"), File::FNM_EXTGLOB)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Nucop
2
+ VERSION = "1.0.0"
3
+ end
data/lib/nucop.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "nucop/version"
2
+
3
+ require "rubocop"
4
+
5
+ Dir[File.join(__dir__, "nucop/helpers/**/*.rb")].each { |f| require f }
6
+ Dir[File.join(__dir__, "nucop/cops/**/*.rb")].each { |f| require f }
7
+
8
+ module Nucop
9
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nucop-cops
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Schweier
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rubocop
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.66'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.66'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.2'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.2'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.13'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.13'
54
+ email:
55
+ - jasons@nulogy.com
56
+ executables: []
57
+ extensions: []
58
+ extra_rdoc_files: []
59
+ files:
60
+ - lib/nucop.rb
61
+ - lib/nucop/cops/explicit_factory_bot_usage.rb
62
+ - lib/nucop/cops/no_core_method_overrides.rb
63
+ - lib/nucop/cops/no_wip_specs.rb
64
+ - lib/nucop/cops/ordered_hash.rb
65
+ - lib/nucop/cops/release_toggles_use_symbols.rb
66
+ - lib/nucop/cops/shadowing_factory_bot_creation_methods.rb
67
+ - lib/nucop/helpers/factory_bot_helper.rb
68
+ - lib/nucop/helpers/file_path_helper.rb
69
+ - lib/nucop/version.rb
70
+ homepage: https://rubygems.org/gems/nucop-cops
71
+ licenses:
72
+ - MIT
73
+ metadata:
74
+ homepage_uri: https://github.com/nulogy/nucop-cops
75
+ changelog_uri: https://github.com/nulogy/nucop-cops/blob/master/CHANGELOG.md
76
+ bug_tracker_uri: https://github.com/nulogy/nucop-cops/issues
77
+ rubygems_mfa_required: 'true'
78
+ rdoc_options: []
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '3.2'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubygems_version: 4.0.4
93
+ specification_version: 4
94
+ summary: Custom RuboCop cops for Nulogy's Ruby projects.
95
+ test_files: []