rubocop-eightyfourcodes 0.0.2 → 0.0.4
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/.rspec +3 -0
- data/.rubocop.yml +16 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +9 -3
- data/Gemfile.lock +75 -0
- data/LICENSE.md +7 -5
- data/README.md +13 -61
- data/Rakefile +32 -0
- data/config/default.yml +36 -8
- data/lib/rubocop/cop/eighty_four_codes/command_literal_injection.rb +4 -2
- data/lib/rubocop/cop/eighty_four_codes/ensure_redirect.rb +48 -0
- data/lib/rubocop/cop/eighty_four_codes/ruby_version_file.rb +30 -34
- data/lib/rubocop/cop/eightyfourcodes_cops.rb +12 -0
- data/lib/rubocop/cop/gitlab_security/deep_munge.rb +36 -0
- data/lib/rubocop/cop/gitlab_security/json_serialization.rb +137 -0
- data/lib/rubocop/cop/gitlab_security/public_send.rb +47 -0
- data/lib/rubocop/cop/gitlab_security/redirect_to_params_update.rb +38 -0
- data/lib/rubocop/cop/gitlab_security/send_file_params.rb +40 -0
- data/lib/rubocop/cop/gitlab_security/sql_injection.rb +41 -0
- data/lib/rubocop/cop/gitlab_security/system_command_injection.rb +38 -0
- data/lib/rubocop/{eighty_four_codes → eightyfourcodes}/inject.rb +5 -1
- data/lib/rubocop/eightyfourcodes/version.rb +7 -0
- data/lib/rubocop/{eighty_four_codes.rb → eightyfourcodes.rb} +6 -1
- data/lib/rubocop-eightyfourcodes.rb +5 -16
- data/rubocop-eightyfourcodes.gemspec +22 -23
- data/sig/rubocop/eightyfourcodes.rbs +6 -0
- metadata +32 -50
- data/CONTRIBUTING.md +0 -3
- data/lib/rubocop/cop/eighty_four_codes/cop.rb +0 -70
- data/lib/rubocop/cop/eighty_four_codes/shell_escape.rb +0 -62
- data/lib/rubocop/eighty_four_codes/concept.rb +0 -34
- data/lib/rubocop/eighty_four_codes/config_formatter.rb +0 -33
- data/lib/rubocop/eighty_four_codes/description_extractor.rb +0 -72
- data/lib/rubocop/eighty_four_codes/example.rb +0 -32
- data/lib/rubocop/eighty_four_codes/example_group.rb +0 -95
- data/lib/rubocop/eighty_four_codes/hook.rb +0 -49
- data/lib/rubocop/eighty_four_codes/language/node_pattern.rb +0 -20
- data/lib/rubocop/eighty_four_codes/language.rb +0 -118
- data/lib/rubocop/eighty_four_codes/top_level_describe.rb +0 -57
- data/lib/rubocop/eighty_four_codes/util.rb +0 -19
- data/lib/rubocop/eighty_four_codes/version.rb +0 -10
- data/lib/rubocop/eighty_four_codes/wording.rb +0 -81
@@ -1,70 +0,0 @@
|
|
1
|
-
module RuboCop
|
2
|
-
module Cop # rubocop:disable Style/Documentation
|
3
|
-
WorkaroundCop84 = Cop.dup
|
4
|
-
|
5
|
-
# Clone of the the normal RuboCop::Cop::Cop class so we can rewrite
|
6
|
-
# the inherited method without breaking functionality
|
7
|
-
class WorkaroundCop84
|
8
|
-
# Overwrite the cop inherited method to be a noop. Our RSpec::Cop
|
9
|
-
# class will invoke the inherited hook instead
|
10
|
-
def self.inherited(*); end
|
11
|
-
|
12
|
-
# Special case `Module#<` so that the rspec support rubocop exports
|
13
|
-
# is compatible with our subclass
|
14
|
-
def self.<(other)
|
15
|
-
other.equal?(RuboCop::Cop::Cop) || super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
private_constant(:WorkaroundCop84)
|
19
|
-
|
20
|
-
module EightyFourCodes
|
21
|
-
# @abstract parent class to rspec cops
|
22
|
-
#
|
23
|
-
# The criteria for whether rubocop-rspec analyzes a certain ruby file
|
24
|
-
# is configured via `AllCops/RSpec`. For example, if you want to
|
25
|
-
# customize your project to scan all files within a `test/` directory
|
26
|
-
# then you could add this to your configuration:
|
27
|
-
#
|
28
|
-
# @example configuring analyzed paths
|
29
|
-
#
|
30
|
-
# AllCops:
|
31
|
-
# RSpec:
|
32
|
-
# Patterns:
|
33
|
-
# - '_test.rb$'
|
34
|
-
# - '(?:^|/)test/'
|
35
|
-
class Cop < WorkaroundCop84
|
36
|
-
include RuboCop::EightyFourCodes::Language
|
37
|
-
include RuboCop::EightyFourCodes::Language::NodePattern
|
38
|
-
|
39
|
-
DEFAULT_CONFIGURATION =
|
40
|
-
RuboCop::EightyFourCodes::CONFIG.fetch('AllCops').fetch('EightyFourCodes')
|
41
|
-
|
42
|
-
# Invoke the original inherited hook so our cops are recognized
|
43
|
-
def self.inherited(subclass)
|
44
|
-
RuboCop::Cop::Cop.inherited(subclass)
|
45
|
-
end
|
46
|
-
|
47
|
-
def relevant_file?(file)
|
48
|
-
relevant_rubocop_rspec_file?(file) && super
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def relevant_rubocop_rspec_file?(file)
|
54
|
-
rspec_pattern =~ file
|
55
|
-
end
|
56
|
-
|
57
|
-
def rspec_pattern
|
58
|
-
Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
|
59
|
-
end
|
60
|
-
|
61
|
-
def rspec_pattern_config
|
62
|
-
config
|
63
|
-
.for_all_cops
|
64
|
-
.fetch('EightyFourCodes', DEFAULT_CONFIGURATION)
|
65
|
-
.fetch('Patterns')
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# TODO: when finished, run `rake generate_cops_documentation` to update the docs
|
4
|
-
module RuboCop
|
5
|
-
module Cop
|
6
|
-
module EightyFourCodes
|
7
|
-
# TODO: Write cop description and example of bad / good code. For every
|
8
|
-
# `SupportedStyle` and unique configuration, there needs to be examples.
|
9
|
-
# Examples must have valid Ruby syntax. Do not use upticks.
|
10
|
-
#
|
11
|
-
# @example EnforcedStyle: bar (default)
|
12
|
-
# # Description of the `bar` style.
|
13
|
-
#
|
14
|
-
# # bad
|
15
|
-
# bad_bar_method
|
16
|
-
#
|
17
|
-
# # bad
|
18
|
-
# bad_bar_method(args)
|
19
|
-
#
|
20
|
-
# # good
|
21
|
-
# good_bar_method
|
22
|
-
#
|
23
|
-
# # good
|
24
|
-
# good_bar_method(args)
|
25
|
-
#
|
26
|
-
# @example EnforcedStyle: foo
|
27
|
-
# # Description of the `foo` style.
|
28
|
-
#
|
29
|
-
# # bad
|
30
|
-
# bad_foo_method
|
31
|
-
#
|
32
|
-
# # bad
|
33
|
-
# bad_foo_method(args)
|
34
|
-
#
|
35
|
-
# # good
|
36
|
-
# good_foo_method
|
37
|
-
#
|
38
|
-
# # good
|
39
|
-
# good_foo_method(args)
|
40
|
-
#
|
41
|
-
class ShellEscape < Cop
|
42
|
-
# TODO: Implement the cop in here.
|
43
|
-
#
|
44
|
-
# In many cases, you can use a node matcher for matching node pattern.
|
45
|
-
# See https://github.com/rubocop-hq/rubocop/blob/master/lib/rubocop/node_pattern.rb
|
46
|
-
#
|
47
|
-
# For example
|
48
|
-
MSG = 'Use `#good_method` instead of `#bad_method`.'.freeze
|
49
|
-
|
50
|
-
def_node_matcher :bad_method?, <<~PATTERN
|
51
|
-
(send nil? :bad_method ...)
|
52
|
-
PATTERN
|
53
|
-
|
54
|
-
def on_send(node)
|
55
|
-
return unless bad_method?(node)
|
56
|
-
|
57
|
-
add_offense(node)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# Wrapper for RSpec DSL methods
|
6
|
-
class Concept
|
7
|
-
include Language
|
8
|
-
include Language::NodePattern
|
9
|
-
extend NodePattern::Macros
|
10
|
-
|
11
|
-
def initialize(node)
|
12
|
-
@node = node
|
13
|
-
end
|
14
|
-
|
15
|
-
def eql?(other)
|
16
|
-
node == other.node
|
17
|
-
end
|
18
|
-
|
19
|
-
alias == eql?
|
20
|
-
|
21
|
-
def hash
|
22
|
-
[self.class, node].hash
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_node
|
26
|
-
node
|
27
|
-
end
|
28
|
-
|
29
|
-
protected
|
30
|
-
|
31
|
-
attr_reader :node
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# Builds a YAML config file from two config hashes
|
6
|
-
class ConfigFormatter
|
7
|
-
NAMESPACES = /^(#{Regexp.union('eightyfourcodes')})/
|
8
|
-
|
9
|
-
def initialize(config, descriptions)
|
10
|
-
@config = config
|
11
|
-
@descriptions = descriptions
|
12
|
-
end
|
13
|
-
|
14
|
-
def dump
|
15
|
-
YAML.dump(unified_config).gsub(NAMESPACES, "\n\\1")
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def unified_config
|
21
|
-
cops.each_with_object(config.dup) do |cop, unified|
|
22
|
-
unified[cop] = config.fetch(cop).merge(descriptions.fetch(cop))
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def cops
|
27
|
-
(descriptions.keys | config.keys).grep(NAMESPACES)
|
28
|
-
end
|
29
|
-
|
30
|
-
attr_reader :config, :descriptions
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
module RuboCop
|
2
|
-
module EightyFourCodes
|
3
|
-
# Extracts cop descriptions from YARD docstrings
|
4
|
-
class DescriptionExtractor
|
5
|
-
def initialize(yardocs)
|
6
|
-
@code_objects = yardocs.map(&CodeObject.public_method(:new))
|
7
|
-
end
|
8
|
-
|
9
|
-
def to_h
|
10
|
-
code_objects
|
11
|
-
.select(&:rspec_cop?)
|
12
|
-
.map(&:configuration)
|
13
|
-
.reduce(:merge)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
attr_reader :code_objects
|
19
|
-
|
20
|
-
# Decorator of a YARD code object for working with documented rspec cops
|
21
|
-
class CodeObject
|
22
|
-
RSPEC_NAMESPACE = 'RuboCop::Cop::eightyfourcodes'.freeze
|
23
|
-
|
24
|
-
def initialize(yardoc)
|
25
|
-
@yardoc = yardoc
|
26
|
-
end
|
27
|
-
|
28
|
-
# Test if the YARD code object documents a concrete rspec cop class
|
29
|
-
#
|
30
|
-
# @return [Boolean]
|
31
|
-
def rspec_cop?
|
32
|
-
class_documentation? && rspec_cop_namespace? && !abstract?
|
33
|
-
end
|
34
|
-
|
35
|
-
# Configuration for the documented cop that would live in default.yml
|
36
|
-
#
|
37
|
-
# @return [Hash]
|
38
|
-
def configuration
|
39
|
-
{ cop_name => { 'Description' => description } }
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def cop_name
|
45
|
-
Object.const_get(documented_constant).cop_name
|
46
|
-
end
|
47
|
-
|
48
|
-
def description
|
49
|
-
yardoc.docstring.split("\n\n").first.to_s
|
50
|
-
end
|
51
|
-
|
52
|
-
def class_documentation?
|
53
|
-
yardoc.type.equal?(:class)
|
54
|
-
end
|
55
|
-
|
56
|
-
def rspec_cop_namespace?
|
57
|
-
documented_constant.start_with?(RSPEC_NAMESPACE)
|
58
|
-
end
|
59
|
-
|
60
|
-
def documented_constant
|
61
|
-
yardoc.to_s
|
62
|
-
end
|
63
|
-
|
64
|
-
def abstract?
|
65
|
-
yardoc.tags.any? { |tag| tag.tag_name.eql?('abstract') }
|
66
|
-
end
|
67
|
-
|
68
|
-
attr_reader :yardoc
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# Wrapper for RSpec examples
|
6
|
-
class Example < Concept
|
7
|
-
def_node_matcher :extract_doc_string, '(send _ _ $str ...)'
|
8
|
-
def_node_matcher :extract_metadata, '(send _ _ _ $...)'
|
9
|
-
def_node_matcher :extract_implementation, '(block send args $_)'
|
10
|
-
|
11
|
-
def doc_string
|
12
|
-
extract_doc_string(definition)
|
13
|
-
end
|
14
|
-
|
15
|
-
def metadata
|
16
|
-
extract_metadata(definition)
|
17
|
-
end
|
18
|
-
|
19
|
-
def implementation
|
20
|
-
extract_implementation(node)
|
21
|
-
end
|
22
|
-
|
23
|
-
def definition
|
24
|
-
if node.send_type?
|
25
|
-
node
|
26
|
-
else
|
27
|
-
node.children.first
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# Wrapper for RSpec example groups
|
6
|
-
class ExampleGroup < Concept
|
7
|
-
# @!method scope_change?(node)
|
8
|
-
#
|
9
|
-
# Detect if the node is an example group or shared example
|
10
|
-
#
|
11
|
-
# Selectors which indicate that we should stop searching
|
12
|
-
#
|
13
|
-
def_node_matcher :scope_change?,
|
14
|
-
(ExampleGroups::ALL + SharedGroups::ALL).block_pattern
|
15
|
-
|
16
|
-
# @!method hook(node)
|
17
|
-
#
|
18
|
-
# Detect if node is `before`, `after`, `around`
|
19
|
-
def_node_matcher :hook, <<-PATTERN
|
20
|
-
(block {$(send nil #{Hooks::ALL.node_pattern_union} ...)} ...)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def_node_matcher :subject, Subject::ALL.block_pattern
|
24
|
-
|
25
|
-
def subjects
|
26
|
-
subjects_in_scope(node)
|
27
|
-
end
|
28
|
-
|
29
|
-
def examples
|
30
|
-
examples_in_scope(node).map(&Example.public_method(:new))
|
31
|
-
end
|
32
|
-
|
33
|
-
def hooks
|
34
|
-
hooks_in_scope(node).map(&Hook.public_method(:new))
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def subjects_in_scope(node)
|
40
|
-
node.each_child_node.flat_map do |child|
|
41
|
-
find_subjects(child)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def find_subjects(node)
|
46
|
-
return [] if scope_change?(node)
|
47
|
-
|
48
|
-
if subject(node)
|
49
|
-
[node]
|
50
|
-
else
|
51
|
-
subjects_in_scope(node)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def hooks_in_scope(node)
|
56
|
-
node.each_child_node.flat_map do |child|
|
57
|
-
find_hooks(child)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def find_hooks(node)
|
62
|
-
return [] if scope_change?(node) || example?(node)
|
63
|
-
|
64
|
-
if hook(node)
|
65
|
-
[node]
|
66
|
-
else
|
67
|
-
hooks_in_scope(node)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def examples_in_scope(node, &blk)
|
72
|
-
node.each_child_node.flat_map do |child|
|
73
|
-
find_examples(child, &blk)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Recursively search for examples within the current scope
|
78
|
-
#
|
79
|
-
# Searches node for examples and halts when a scope change is detected
|
80
|
-
#
|
81
|
-
# @param node [RuboCop::Node] node to recursively search for examples
|
82
|
-
#
|
83
|
-
# @return [Array<RuboCop::Node>] discovered example nodes
|
84
|
-
def find_examples(node)
|
85
|
-
return [] if scope_change?(node)
|
86
|
-
|
87
|
-
if example?(node)
|
88
|
-
[node]
|
89
|
-
else
|
90
|
-
examples_in_scope(node)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# Wrapper for RSpec hook
|
6
|
-
class Hook < Concept
|
7
|
-
STANDARDIZED_SCOPES = %i[each context suite].freeze
|
8
|
-
private_constant(:STANDARDIZED_SCOPES)
|
9
|
-
|
10
|
-
def name
|
11
|
-
node.method_name
|
12
|
-
end
|
13
|
-
|
14
|
-
def knowable_scope?
|
15
|
-
return true unless scope_argument
|
16
|
-
|
17
|
-
scope_argument.sym_type?
|
18
|
-
end
|
19
|
-
|
20
|
-
def valid_scope?
|
21
|
-
STANDARDIZED_SCOPES.include?(scope)
|
22
|
-
end
|
23
|
-
|
24
|
-
def example?
|
25
|
-
scope.equal?(:each)
|
26
|
-
end
|
27
|
-
|
28
|
-
def scope
|
29
|
-
case scope_name
|
30
|
-
when nil, :each, :example then :each
|
31
|
-
when :context, :all then :context
|
32
|
-
when :suite then :suite
|
33
|
-
else
|
34
|
-
scope_name
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def scope_name
|
41
|
-
scope_argument.to_a.first
|
42
|
-
end
|
43
|
-
|
44
|
-
def scope_argument
|
45
|
-
node.first_argument
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
module Language
|
6
|
-
# Common node matchers used for matching against the rspec DSL
|
7
|
-
module NodePattern
|
8
|
-
extend RuboCop::NodePattern::Macros
|
9
|
-
|
10
|
-
def_node_matcher :example_group?, ExampleGroups::ALL.block_pattern
|
11
|
-
|
12
|
-
def_node_matcher :example_group_with_body?, <<-PATTERN
|
13
|
-
(block #{ExampleGroups::ALL.send_pattern} args [!nil])
|
14
|
-
PATTERN
|
15
|
-
|
16
|
-
def_node_matcher :example?, Examples::ALL.block_pattern
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,118 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# RSpec public API methods that are commonly used in cops
|
6
|
-
module Language
|
7
|
-
# Set of method selectors
|
8
|
-
class SelectorSet
|
9
|
-
def initialize(selectors)
|
10
|
-
@selectors = selectors
|
11
|
-
end
|
12
|
-
|
13
|
-
def ==(other)
|
14
|
-
selectors.eql?(other.selectors)
|
15
|
-
end
|
16
|
-
|
17
|
-
def +(other)
|
18
|
-
self.class.new(selectors + other.selectors)
|
19
|
-
end
|
20
|
-
|
21
|
-
def include?(selector)
|
22
|
-
selectors.include?(selector)
|
23
|
-
end
|
24
|
-
|
25
|
-
def block_pattern
|
26
|
-
"(block #{send_pattern} ...)"
|
27
|
-
end
|
28
|
-
|
29
|
-
def send_pattern
|
30
|
-
"(send _ #{node_pattern_union} ...)"
|
31
|
-
end
|
32
|
-
|
33
|
-
def node_pattern_union
|
34
|
-
"{#{node_pattern}}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def node_pattern
|
38
|
-
selectors.map(&:inspect).join(' ')
|
39
|
-
end
|
40
|
-
|
41
|
-
protected
|
42
|
-
|
43
|
-
attr_reader :selectors
|
44
|
-
end
|
45
|
-
|
46
|
-
module Matchers
|
47
|
-
MESSAGE_CHAIN = SelectorSet.new(%i[receive_message_chain stub_chain])
|
48
|
-
end
|
49
|
-
|
50
|
-
module ExampleGroups
|
51
|
-
GROUPS = SelectorSet.new(%i[describe context feature example_group])
|
52
|
-
SKIPPED = SelectorSet.new(%i[xdescribe xcontext xfeature])
|
53
|
-
FOCUSED = SelectorSet.new(%i[fdescribe fcontext ffeature])
|
54
|
-
|
55
|
-
ALL = GROUPS + SKIPPED + FOCUSED
|
56
|
-
end
|
57
|
-
|
58
|
-
module SharedGroups
|
59
|
-
EXAMPLES = SelectorSet.new(%i[shared_examples shared_examples_for])
|
60
|
-
CONTEXT = SelectorSet.new(%i[shared_context])
|
61
|
-
|
62
|
-
ALL = EXAMPLES + CONTEXT
|
63
|
-
end
|
64
|
-
|
65
|
-
module Includes
|
66
|
-
EXAMPLES = SelectorSet.new(
|
67
|
-
%i[
|
68
|
-
it_behaves_like
|
69
|
-
it_should_behave_like
|
70
|
-
include_examples
|
71
|
-
]
|
72
|
-
)
|
73
|
-
CONTEXT = SelectorSet.new(%i[include_context])
|
74
|
-
|
75
|
-
ALL = EXAMPLES + CONTEXT
|
76
|
-
end
|
77
|
-
|
78
|
-
module Examples
|
79
|
-
EXAMPLES = SelectorSet.new(%i[it specify example scenario its])
|
80
|
-
FOCUSED = SelectorSet.new(%i[fit fspecify fexample fscenario focus])
|
81
|
-
SKIPPED = SelectorSet.new(%i[xit xspecify xexample xscenario skip])
|
82
|
-
PENDING = SelectorSet.new(%i[pending])
|
83
|
-
|
84
|
-
ALL = EXAMPLES + FOCUSED + SKIPPED + PENDING
|
85
|
-
end
|
86
|
-
|
87
|
-
module Hooks
|
88
|
-
ALL = SelectorSet.new(
|
89
|
-
%i[
|
90
|
-
prepend_before
|
91
|
-
before
|
92
|
-
append_before
|
93
|
-
around
|
94
|
-
prepend_after
|
95
|
-
after
|
96
|
-
append_after
|
97
|
-
]
|
98
|
-
)
|
99
|
-
end
|
100
|
-
|
101
|
-
module Helpers
|
102
|
-
ALL = SelectorSet.new(%i[let let!])
|
103
|
-
end
|
104
|
-
|
105
|
-
module Subject
|
106
|
-
ALL = SelectorSet.new(%i[subject subject!])
|
107
|
-
end
|
108
|
-
|
109
|
-
ALL =
|
110
|
-
ExampleGroups::ALL +
|
111
|
-
SharedGroups::ALL +
|
112
|
-
Examples::ALL +
|
113
|
-
Hooks::ALL +
|
114
|
-
Helpers::ALL +
|
115
|
-
Subject::ALL
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
module RuboCop
|
2
|
-
module EightyFourCodes
|
3
|
-
# Helper methods for top level describe cops
|
4
|
-
module TopLevelDescribe
|
5
|
-
extend NodePattern::Macros
|
6
|
-
|
7
|
-
def_node_matcher :described_constant, <<-PATTERN
|
8
|
-
(block $(send _ :describe $(const ...)) (args) $_)
|
9
|
-
PATTERN
|
10
|
-
|
11
|
-
def on_send(node)
|
12
|
-
return unless respond_to?(:on_top_level_describe)
|
13
|
-
return unless top_level_describe?(node)
|
14
|
-
|
15
|
-
_receiver, _method_name, *args = *node
|
16
|
-
|
17
|
-
on_top_level_describe(node, args)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def top_level_describe?(node)
|
23
|
-
_receiver, method_name, *_args = *node
|
24
|
-
return false unless method_name == :describe
|
25
|
-
|
26
|
-
top_level_nodes.include?(node)
|
27
|
-
end
|
28
|
-
|
29
|
-
def top_level_nodes
|
30
|
-
nodes = describe_statement_children(root_node)
|
31
|
-
# If we have no top level describe statements, we need to check any
|
32
|
-
# blocks on the top level (e.g. after a require).
|
33
|
-
if nodes.empty?
|
34
|
-
nodes = root_node.each_child_node(:block).flat_map do |child|
|
35
|
-
describe_statement_children(child)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
nodes
|
40
|
-
end
|
41
|
-
|
42
|
-
def root_node
|
43
|
-
processed_source.ast
|
44
|
-
end
|
45
|
-
|
46
|
-
def single_top_level_describe?
|
47
|
-
top_level_nodes.one?
|
48
|
-
end
|
49
|
-
|
50
|
-
def describe_statement_children(node)
|
51
|
-
node.each_child_node(:send).select do |element|
|
52
|
-
element.children[1] == :describe
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module EightyFourCodes
|
5
|
-
# Utility methods
|
6
|
-
module Util
|
7
|
-
# Error raised by `Util.one` if size is less than zero or greater than one
|
8
|
-
SizeError = Class.new(IndexError)
|
9
|
-
|
10
|
-
# Return only element in array if it contains exactly one member
|
11
|
-
def one(array)
|
12
|
-
return array.first if array.one?
|
13
|
-
|
14
|
-
raise SizeError,
|
15
|
-
"expected size to be exactly 1 but size was #{array.size}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|