reek 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -21
- data/.travis.yml +1 -0
- data/.yardopts +3 -6
- data/CHANGELOG +6 -0
- data/CONTRIBUTING.md +8 -3
- data/README.md +94 -42
- data/config/defaults.reek +0 -1
- data/docs/API.md +50 -0
- data/docs/Attribute.md +43 -0
- data/docs/Basic-Smell-Options.md +44 -0
- data/docs/Boolean-Parameter.md +52 -0
- data/docs/Class-Variable.md +40 -0
- data/docs/Code-Smells.md +34 -0
- data/docs/Command-Line-Options.md +84 -0
- data/docs/Configuration-Files.md +38 -0
- data/docs/Control-Couple.md +22 -0
- data/docs/Control-Parameter.md +29 -0
- data/docs/Data-Clump.md +44 -0
- data/docs/Duplicate-Method-Call.md +49 -0
- data/docs/Feature-Envy.md +29 -0
- data/docs/How-reek-works-internally.md +44 -0
- data/docs/Irresponsible-Module.md +39 -0
- data/docs/Large-Class.md +20 -0
- data/docs/Long-Parameter-List.md +38 -0
- data/docs/Long-Yield-List.md +36 -0
- data/docs/Module-Initialize.md +62 -0
- data/docs/Nested-Iterators.md +38 -0
- data/docs/Nil-Check.md +39 -0
- data/docs/Prima-Donna-Method.md +53 -0
- data/docs/RSpec-matchers.md +133 -0
- data/docs/Rake-Task.md +58 -0
- data/docs/Reek-Driven-Development.md +45 -0
- data/docs/Repeated-Conditional.md +44 -0
- data/docs/Simulated-Polymorphism.md +16 -0
- data/docs/Smell-Suppression.md +32 -0
- data/docs/Too-Many-Instance-Variables.md +43 -0
- data/docs/Too-Many-Methods.md +55 -0
- data/docs/Too-Many-Statements.md +50 -0
- data/docs/Uncommunicative-Method-Name.md +24 -0
- data/docs/Uncommunicative-Module-Name.md +23 -0
- data/docs/Uncommunicative-Name.md +16 -0
- data/docs/Uncommunicative-Parameter-Name.md +24 -0
- data/docs/Uncommunicative-Variable-Name.md +24 -0
- data/docs/Unused-Parameters.md +27 -0
- data/docs/Utility-Function.md +46 -0
- data/docs/Versioning-Policy.md +7 -0
- data/docs/YAML-Reports.md +111 -0
- data/docs/yard_plugin.rb +14 -0
- data/features/command_line_interface/options.feature +1 -0
- data/features/programmatic_access.feature +1 -1
- data/features/samples.feature +3 -3
- data/lib/reek.rb +2 -2
- data/lib/reek/cli/input.rb +2 -2
- data/lib/reek/cli/option_interpreter.rb +2 -0
- data/lib/reek/cli/options.rb +10 -4
- data/lib/reek/cli/reek_command.rb +2 -2
- data/lib/reek/cli/report/report.rb +60 -0
- data/lib/reek/cli/silencer.rb +13 -0
- data/lib/reek/{source → core}/ast_node.rb +1 -1
- data/lib/reek/{source → core}/ast_node_class_map.rb +10 -11
- data/lib/reek/{source → core}/code_comment.rb +1 -1
- data/lib/reek/core/code_context.rb +1 -1
- data/lib/reek/core/examiner.rb +85 -0
- data/lib/reek/core/method_context.rb +1 -1
- data/lib/reek/core/module_context.rb +2 -2
- data/lib/reek/core/reference_collector.rb +31 -0
- data/lib/reek/core/singleton_method_context.rb +0 -4
- data/lib/reek/core/smell_repository.rb +4 -2
- data/lib/reek/{source → core}/tree_dresser.rb +1 -1
- data/lib/reek/{source → sexp}/sexp_extensions.rb +5 -5
- data/lib/reek/sexp/sexp_formatter.rb +29 -0
- data/lib/reek/sexp/sexp_node.rb +91 -0
- data/lib/reek/smells.rb +4 -2
- data/lib/reek/smells/attribute.rb +35 -7
- data/lib/reek/smells/boolean_parameter.rb +1 -1
- data/lib/reek/smells/class_variable.rb +1 -1
- data/lib/reek/smells/control_parameter.rb +1 -1
- data/lib/reek/smells/data_clump.rb +1 -1
- data/lib/reek/smells/duplicate_method_call.rb +12 -4
- data/lib/reek/smells/feature_envy.rb +1 -1
- data/lib/reek/smells/irresponsible_module.rb +3 -3
- data/lib/reek/smells/long_parameter_list.rb +1 -1
- data/lib/reek/smells/long_yield_list.rb +1 -1
- data/lib/reek/smells/module_initialize.rb +1 -1
- data/lib/reek/smells/nested_iterators.rb +1 -1
- data/lib/reek/smells/nil_check.rb +3 -2
- data/lib/reek/smells/prima_donna_method.rb +18 -11
- data/lib/reek/smells/repeated_conditional.rb +3 -3
- data/lib/reek/smells/smell_detector.rb +5 -1
- data/lib/reek/smells/smell_warning.rb +99 -0
- data/lib/reek/smells/too_many_instance_variables.rb +1 -1
- data/lib/reek/smells/too_many_methods.rb +1 -1
- data/lib/reek/smells/too_many_statements.rb +1 -1
- data/lib/reek/smells/uncommunicative_method_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_module_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_parameter_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +1 -1
- data/lib/reek/smells/unused_parameters.rb +1 -1
- data/lib/reek/smells/utility_function.rb +3 -16
- data/lib/reek/source/source_code.rb +31 -13
- data/lib/reek/source/source_locator.rb +16 -17
- data/lib/reek/source/source_repository.rb +10 -11
- data/lib/reek/spec/should_reek.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +2 -2
- data/lib/reek/spec/should_reek_only_of.rb +2 -2
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +3 -4
- data/spec/factories/factories.rb +1 -1
- data/spec/gem/yard_spec.rb +1 -1
- data/spec/quality/reek_source_spec.rb +2 -2
- data/spec/reek/cli/html_report_spec.rb +3 -3
- data/spec/reek/cli/json_report_spec.rb +3 -3
- data/spec/reek/cli/{option_interperter_spec.rb → option_interpreter_spec.rb} +1 -1
- data/spec/reek/cli/options_spec.rb +19 -0
- data/spec/reek/cli/text_report_spec.rb +7 -7
- data/spec/reek/cli/xml_report_spec.rb +34 -0
- data/spec/reek/cli/yaml_report_spec.rb +3 -3
- data/spec/reek/configuration/app_configuration_spec.rb +1 -1
- data/spec/reek/configuration/configuration_file_finder_spec.rb +22 -1
- data/spec/reek/{source → core}/code_comment_spec.rb +14 -14
- data/spec/reek/core/code_context_spec.rb +1 -1
- data/spec/reek/{examiner_spec.rb → core/examiner_spec.rb} +12 -12
- data/spec/reek/core/method_context_spec.rb +27 -22
- data/spec/reek/core/module_context_spec.rb +2 -2
- data/spec/reek/core/object_refs_spec.rb +1 -1
- data/spec/reek/{source → core}/object_source_spec.rb +1 -1
- data/spec/reek/{source → core}/reference_collector_spec.rb +25 -16
- data/spec/reek/core/singleton_method_context_spec.rb +12 -2
- data/spec/reek/core/smell_configuration_spec.rb +1 -1
- data/spec/reek/core/smell_repository_spec.rb +12 -1
- data/spec/reek/core/stop_context_spec.rb +1 -1
- data/spec/reek/core/tree_dresser_spec.rb +16 -0
- data/spec/reek/core/tree_walker_spec.rb +3 -3
- data/spec/reek/core/warning_collector_spec.rb +6 -6
- data/spec/reek/{source → sexp}/sexp_extensions_spec.rb +8 -8
- data/spec/reek/{source → sexp}/sexp_formatter_spec.rb +11 -5
- data/spec/reek/{source → sexp}/sexp_node_spec.rb +3 -3
- data/spec/reek/smells/attribute_spec.rb +89 -85
- data/spec/reek/smells/behaves_like_variable_detector.rb +1 -1
- data/spec/reek/smells/boolean_parameter_spec.rb +1 -1
- data/spec/reek/smells/class_variable_spec.rb +1 -1
- data/spec/reek/smells/control_parameter_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +2 -2
- data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
- data/spec/reek/smells/feature_envy_spec.rb +2 -2
- data/spec/reek/smells/irresponsible_module_spec.rb +1 -1
- data/spec/reek/smells/long_parameter_list_spec.rb +2 -2
- data/spec/reek/smells/long_yield_list_spec.rb +1 -1
- data/spec/reek/smells/module_initialize_spec.rb +1 -1
- data/spec/reek/smells/nested_iterators_spec.rb +2 -2
- data/spec/reek/smells/nil_check_spec.rb +1 -1
- data/spec/reek/smells/prima_donna_method_spec.rb +1 -1
- data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
- data/spec/reek/smells/smell_detector_shared.rb +2 -2
- data/spec/reek/{smell_warning_spec.rb → smells/smell_warning_spec.rb} +7 -7
- data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smells/too_many_methods_spec.rb +1 -1
- data/spec/reek/smells/too_many_statements_spec.rb +4 -4
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
- data/spec/reek/smells/unused_parameters_spec.rb +1 -1
- data/spec/reek/smells/utility_function_spec.rb +1 -1
- data/spec/reek/source/source_code_spec.rb +1 -1
- data/spec/reek/spec/should_reek_of_spec.rb +1 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +1 -1
- data/spec/reek/spec/should_reek_spec.rb +1 -1
- data/spec/samples/checkstyle.xml +2 -0
- data/spec/spec_helper.rb +15 -3
- metadata +68 -38
- data/.ruby-gemset +0 -1
- data/lib/reek/examiner.rb +0 -79
- data/lib/reek/smell_warning.rb +0 -87
- data/lib/reek/source/reference_collector.rb +0 -27
- data/lib/reek/source/sexp_formatter.rb +0 -22
- data/lib/reek/source/sexp_node.rb +0 -79
- data/spec/reek/source/tree_dresser_spec.rb +0 -16
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
reek
|
data/lib/reek/examiner.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require_relative 'source/source_repository'
|
2
|
-
require_relative 'core/warning_collector'
|
3
|
-
require_relative 'core/smell_repository'
|
4
|
-
require_relative 'core/tree_walker'
|
5
|
-
|
6
|
-
module Reek
|
7
|
-
#
|
8
|
-
# Applies all available smell detectors to a source.
|
9
|
-
#
|
10
|
-
class Examiner
|
11
|
-
#
|
12
|
-
# A simple description of the source being analysed for smells.
|
13
|
-
# If the source is a single File, this will be the file's path.
|
14
|
-
#
|
15
|
-
attr_accessor :description
|
16
|
-
|
17
|
-
#
|
18
|
-
# Creates an Examiner which scans the given +source+ for code smells.
|
19
|
-
#
|
20
|
-
# @param [Source::SourceCode, Array<String>, #to_reek_source]
|
21
|
-
# If +source+ is a String it is assumed to be Ruby source code;
|
22
|
-
# if it is a File, the file is opened and parsed for Ruby source code;
|
23
|
-
# and if it is an Array, it is assumed to be a list of file paths,
|
24
|
-
# each of which is opened and parsed for source code.
|
25
|
-
#
|
26
|
-
def initialize(source, smell_types_to_filter_by = [])
|
27
|
-
@sources = Source::SourceRepository.parse(source)
|
28
|
-
@description = @sources.description
|
29
|
-
@collector = Core::WarningCollector.new
|
30
|
-
@smell_types = eligible_smell_types(smell_types_to_filter_by)
|
31
|
-
|
32
|
-
run
|
33
|
-
end
|
34
|
-
|
35
|
-
#
|
36
|
-
# List the smells found in the source.
|
37
|
-
#
|
38
|
-
# @return [Array<SmellWarning>]
|
39
|
-
#
|
40
|
-
def smells
|
41
|
-
@smells ||= @collector.warnings
|
42
|
-
end
|
43
|
-
|
44
|
-
#
|
45
|
-
# Returns the number of smells found in the source
|
46
|
-
#
|
47
|
-
def smells_count
|
48
|
-
smells.length
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# True if and only if there are code smells in the source.
|
53
|
-
#
|
54
|
-
def smelly?
|
55
|
-
!smells.empty?
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def run
|
61
|
-
@sources.each do |source|
|
62
|
-
smell_repository = Core::SmellRepository.new(source.desc, @smell_types)
|
63
|
-
syntax_tree = source.syntax_tree
|
64
|
-
Core::TreeWalker.new(smell_repository).process(syntax_tree) if syntax_tree
|
65
|
-
smell_repository.report_on(@collector)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def eligible_smell_types(smell_types_to_filter_by = [])
|
70
|
-
if smell_types_to_filter_by.any?
|
71
|
-
Core::SmellRepository.smell_types.select do |klass|
|
72
|
-
smell_types_to_filter_by.include? klass.smell_type
|
73
|
-
end
|
74
|
-
else
|
75
|
-
Core::SmellRepository.smell_types
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/lib/reek/smell_warning.rb
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
|
-
module Reek
|
4
|
-
#
|
5
|
-
# Reports a warning that a smell has been found.
|
6
|
-
#
|
7
|
-
class SmellWarning
|
8
|
-
include Comparable
|
9
|
-
extend Forwardable
|
10
|
-
attr_accessor :smell_detector, :context, :lines, :message, :parameters
|
11
|
-
def_delegators :smell_detector, :smell_category, :smell_type, :source
|
12
|
-
|
13
|
-
def initialize(smell_detector, options = {})
|
14
|
-
self.smell_detector = smell_detector
|
15
|
-
self.context = options.fetch(:context, '').to_s
|
16
|
-
self.lines = options.fetch(:lines)
|
17
|
-
self.message = options.fetch(:message)
|
18
|
-
self.parameters = options.fetch(:parameters, {})
|
19
|
-
end
|
20
|
-
|
21
|
-
def smell_classes
|
22
|
-
[smell_detector.smell_category, smell_detector.smell_type]
|
23
|
-
end
|
24
|
-
|
25
|
-
def hash
|
26
|
-
sort_key.hash
|
27
|
-
end
|
28
|
-
|
29
|
-
def <=>(other)
|
30
|
-
sort_key <=> other.sort_key
|
31
|
-
end
|
32
|
-
|
33
|
-
def eql?(other)
|
34
|
-
(self <=> other) == 0
|
35
|
-
end
|
36
|
-
|
37
|
-
def matches?(klass, other_parameters = {})
|
38
|
-
smell_classes.include?(klass.to_s) && common_parameters_equal?(other_parameters)
|
39
|
-
end
|
40
|
-
|
41
|
-
def report_on(listener)
|
42
|
-
listener.found_smell(self)
|
43
|
-
end
|
44
|
-
|
45
|
-
def yaml_hash(warning_formatter = nil)
|
46
|
-
result = {
|
47
|
-
'smell_category' => smell_detector.smell_category,
|
48
|
-
'smell_type' => smell_detector.smell_type,
|
49
|
-
'source' => smell_detector.source,
|
50
|
-
'context' => context,
|
51
|
-
'lines' => lines,
|
52
|
-
'message' => message
|
53
|
-
}
|
54
|
-
if warning_formatter.respond_to?(:explanatory_link)
|
55
|
-
result.merge!('wiki_link' => warning_formatter.explanatory_link(smell_detector))
|
56
|
-
end
|
57
|
-
parameters.each do |key, value|
|
58
|
-
result[key.to_s] = value
|
59
|
-
end
|
60
|
-
result
|
61
|
-
end
|
62
|
-
|
63
|
-
protected
|
64
|
-
|
65
|
-
def sort_key
|
66
|
-
[context, message, smell_category]
|
67
|
-
end
|
68
|
-
|
69
|
-
def common_parameters_equal?(other_parameters)
|
70
|
-
other_parameters.keys.each do |key|
|
71
|
-
unless parameters.key?(key)
|
72
|
-
raise ArgumentError, "The parameter #{key} you want to check for doesn't exist"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Why not check for strict parameter equality instead of just the common ones?
|
77
|
-
#
|
78
|
-
# In `self`, `parameters` might look like this: {:name=>"@other.thing", :count=>2}
|
79
|
-
# Coming from specs, 'other_parameters' might look like this, e.g.:
|
80
|
-
# {:name=>"@other.thing"}
|
81
|
-
# So in this spec we are just specifying the "name" parameter but not the "count".
|
82
|
-
# In order to allow for this kind of leniency we just test for common parameter equality,
|
83
|
-
# not for a strict one.
|
84
|
-
parameters.values_at(*other_parameters.keys) == other_parameters.values
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
|
2
|
-
module Reek
|
3
|
-
module Source
|
4
|
-
#
|
5
|
-
# Locates references to the current object within a portion
|
6
|
-
# of an abstract syntax tree.
|
7
|
-
#
|
8
|
-
class ReferenceCollector
|
9
|
-
STOP_NODES = [:class, :module, :def, :defs]
|
10
|
-
|
11
|
-
def initialize(ast)
|
12
|
-
@ast = ast
|
13
|
-
end
|
14
|
-
|
15
|
-
def num_refs_to_self
|
16
|
-
result = 0
|
17
|
-
[:self, :zsuper, :ivar, :ivasgn].each do |node_type|
|
18
|
-
@ast.look_for(node_type, STOP_NODES) { result += 1 }
|
19
|
-
end
|
20
|
-
@ast.look_for(:send, STOP_NODES) do |call|
|
21
|
-
result += 1 unless call.receiver
|
22
|
-
end
|
23
|
-
result
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
old_verbose, $VERBOSE = $VERBOSE, nil
|
2
|
-
require 'unparser'
|
3
|
-
$VERBOSE = old_verbose
|
4
|
-
|
5
|
-
module Reek
|
6
|
-
module Source
|
7
|
-
#
|
8
|
-
# Formats snippets of syntax tree back into Ruby source code.
|
9
|
-
#
|
10
|
-
class SexpFormatter
|
11
|
-
def self.format(sexp)
|
12
|
-
return sexp.to_s unless sexp.is_a? AST::Node
|
13
|
-
lines = Unparser.unparse(sexp).split "\n"
|
14
|
-
if lines.length > 1
|
15
|
-
"#{lines.first} ... #{lines.last}"
|
16
|
-
else
|
17
|
-
lines.first
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module Reek
|
2
|
-
module Source
|
3
|
-
#
|
4
|
-
# Extensions to +Sexp+ to allow +TreeWalker+ to navigate the abstract
|
5
|
-
# syntax tree more easily.
|
6
|
-
#
|
7
|
-
module SexpNode
|
8
|
-
def self.format(expr)
|
9
|
-
case expr
|
10
|
-
when AST::Node then expr.format_ruby
|
11
|
-
else expr.to_s
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def hash
|
16
|
-
inspect.hash
|
17
|
-
end
|
18
|
-
|
19
|
-
def each_node(type, ignoring = [], &blk)
|
20
|
-
if block_given?
|
21
|
-
look_for(type, ignoring, &blk)
|
22
|
-
else
|
23
|
-
result = []
|
24
|
-
look_for(type, ignoring) { |exp| result << exp }
|
25
|
-
result
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def find_nodes(types, ignoring = [])
|
30
|
-
result = []
|
31
|
-
look_for_alt(types, ignoring) { |exp| result << exp }
|
32
|
-
result
|
33
|
-
end
|
34
|
-
|
35
|
-
def each_sexp
|
36
|
-
children.each { |elem| yield elem if elem.is_a? AST::Node }
|
37
|
-
end
|
38
|
-
|
39
|
-
#
|
40
|
-
# Carries out a depth-first traversal of this syntax tree, yielding
|
41
|
-
# every Sexp of type +target_type+. The traversal ignores any node
|
42
|
-
# whose type is listed in the Array +ignoring+.
|
43
|
-
#
|
44
|
-
def look_for(target_type, ignoring = [], &blk)
|
45
|
-
each_sexp do |elem|
|
46
|
-
elem.look_for(target_type, ignoring, &blk) unless ignoring.include?(elem.type)
|
47
|
-
end
|
48
|
-
blk.call(self) if type == target_type
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# Carries out a depth-first traversal of this syntax tree, yielding
|
53
|
-
# every Sexp of type +target_type+. The traversal ignores any node
|
54
|
-
# whose type is listed in the Array +ignoring+, includeing the top node.
|
55
|
-
#
|
56
|
-
# Also, doesn't nest
|
57
|
-
#
|
58
|
-
def look_for_alt(target_types, ignoring = [], &blk)
|
59
|
-
return if ignoring.include?(type)
|
60
|
-
if target_types.include? type
|
61
|
-
blk.call(self)
|
62
|
-
else
|
63
|
-
each_sexp do |elem|
|
64
|
-
elem.look_for_alt(target_types, ignoring, &blk)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def contains_nested_node?(target_type)
|
70
|
-
look_for(target_type) { |_elem| return true }
|
71
|
-
false
|
72
|
-
end
|
73
|
-
|
74
|
-
def format_ruby
|
75
|
-
SexpFormatter.format(self)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require_relative '../../spec_helper'
|
2
|
-
require_relative '../../../lib/reek/source/tree_dresser'
|
3
|
-
|
4
|
-
describe Reek::Source::TreeDresser do
|
5
|
-
let(:ifnode) { Parser::AST::Node.new(:if) }
|
6
|
-
let(:sendnode) { Parser::AST::Node.new(:send) }
|
7
|
-
let(:dresser) { Reek::Source::TreeDresser.new }
|
8
|
-
|
9
|
-
it 'dresses :if sexp with IfNode' do
|
10
|
-
expect(dresser.dress(ifnode, {})).to be_a Reek::Source::SexpExtensions::IfNode
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'dresses :send sexp with SendNode' do
|
14
|
-
expect(dresser.dress(sendnode, {})).to be_a Reek::Source::SexpExtensions::SendNode
|
15
|
-
end
|
16
|
-
end
|