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 +7 -0
- data/lib/nucop/cops/explicit_factory_bot_usage.rb +40 -0
- data/lib/nucop/cops/no_core_method_overrides.rb +31 -0
- data/lib/nucop/cops/no_wip_specs.rb +35 -0
- data/lib/nucop/cops/ordered_hash.rb +36 -0
- data/lib/nucop/cops/release_toggles_use_symbols.rb +43 -0
- data/lib/nucop/cops/shadowing_factory_bot_creation_methods.rb +37 -0
- data/lib/nucop/helpers/factory_bot_helper.rb +30 -0
- data/lib/nucop/helpers/file_path_helper.rb +13 -0
- data/lib/nucop/version.rb +3 -0
- data/lib/nucop.rb +9 -0
- metadata +95 -0
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
|
data/lib/nucop.rb
ADDED
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: []
|