reek 2.2.1 → 3.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 +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +9 -4
- data/CHANGELOG +8 -0
- data/Gemfile +6 -4
- data/README.md +6 -0
- data/docs/API.md +51 -22
- data/docs/Configuration-Files.md +12 -1
- data/docs/Feature-Envy.md +30 -10
- data/docs/How-reek-works-internally.md +109 -39
- data/docs/RSpec-matchers.md +26 -22
- data/docs/Reek-Driven-Development.md +0 -8
- data/docs/Utility-Function.md +8 -10
- data/features/{ruby_api/api.feature → command_line_interface/basic_usage.feature} +2 -2
- data/features/programmatic_access.feature +21 -2
- data/features/samples.feature +3 -1
- data/lib/reek.rb +2 -2
- data/lib/reek/{core → ast}/ast_node_class_map.rb +8 -8
- data/lib/reek/{sexp/sexp_node.rb → ast/node.rb} +47 -6
- data/lib/reek/{core → ast}/object_refs.rb +2 -1
- data/lib/reek/{core → ast}/reference_collector.rb +2 -1
- data/lib/reek/{sexp → ast}/sexp_extensions.rb +10 -5
- data/lib/reek/{sexp → ast}/sexp_formatter.rb +7 -5
- data/lib/reek/cli/application.rb +1 -0
- data/lib/reek/cli/command.rb +1 -0
- data/lib/reek/cli/input.rb +4 -1
- data/lib/reek/cli/option_interpreter.rb +6 -4
- data/lib/reek/cli/options.rb +2 -1
- data/lib/reek/cli/reek_command.rb +3 -2
- data/lib/reek/cli/silencer.rb +1 -0
- data/lib/reek/{core → cli}/warning_collector.rb +2 -1
- data/lib/reek/code_comment.rb +36 -0
- data/lib/reek/configuration/app_configuration.rb +17 -2
- data/lib/reek/configuration/configuration_file_finder.rb +1 -0
- data/lib/reek/{core → context}/code_context.rb +7 -5
- data/lib/reek/{core → context}/method_context.rb +5 -3
- data/lib/reek/{core → context}/module_context.rb +8 -3
- data/lib/reek/{core/stop_context.rb → context/root_context.rb} +4 -2
- data/lib/reek/{core → context}/singleton_method_context.rb +2 -1
- data/lib/reek/examiner.rb +82 -0
- data/lib/reek/report/formatter.rb +70 -0
- data/lib/reek/report/heading_formatter.rb +45 -0
- data/lib/reek/report/location_formatter.rb +35 -0
- data/lib/reek/report/report.rb +198 -0
- data/lib/reek/smells.rb +24 -13
- data/lib/reek/smells/attribute.rb +6 -4
- data/lib/reek/smells/boolean_parameter.rb +3 -1
- data/lib/reek/smells/class_variable.rb +3 -1
- data/lib/reek/smells/control_parameter.rb +3 -1
- data/lib/reek/smells/data_clump.rb +3 -1
- data/lib/reek/smells/duplicate_method_call.rb +3 -1
- data/lib/reek/smells/feature_envy.rb +3 -1
- data/lib/reek/smells/irresponsible_module.rb +12 -7
- data/lib/reek/smells/long_parameter_list.rb +5 -3
- data/lib/reek/smells/long_yield_list.rb +3 -1
- data/lib/reek/smells/module_initialize.rb +3 -1
- data/lib/reek/smells/nested_iterators.rb +3 -1
- data/lib/reek/smells/nil_check.rb +3 -1
- data/lib/reek/smells/prima_donna_method.rb +3 -1
- data/lib/reek/smells/repeated_conditional.rb +5 -3
- data/lib/reek/{core → smells}/smell_configuration.rb +3 -1
- data/lib/reek/smells/smell_detector.rb +9 -7
- data/lib/reek/{core → smells}/smell_repository.rb +3 -2
- data/lib/reek/smells/smell_warning.rb +6 -4
- data/lib/reek/smells/too_many_instance_variables.rb +3 -1
- data/lib/reek/smells/too_many_methods.rb +3 -1
- data/lib/reek/smells/too_many_statements.rb +3 -1
- data/lib/reek/smells/uncommunicative_method_name.rb +3 -1
- data/lib/reek/smells/uncommunicative_module_name.rb +3 -1
- data/lib/reek/smells/uncommunicative_parameter_name.rb +3 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +3 -1
- data/lib/reek/smells/unused_parameters.rb +3 -1
- data/lib/reek/smells/utility_function.rb +5 -2
- data/lib/reek/source/source_code.rb +40 -9
- data/lib/reek/source/source_locator.rb +30 -12
- data/lib/reek/spec/should_reek.rb +5 -4
- data/lib/reek/spec/should_reek_of.rb +3 -2
- data/lib/reek/spec/should_reek_only_of.rb +5 -4
- data/lib/reek/tree_dresser.rb +32 -0
- data/lib/reek/tree_walker.rb +182 -0
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +3 -3
- data/spec/factories/factories.rb +2 -0
- data/spec/reek/{sexp/sexp_node_spec.rb → ast/node_spec.rb} +2 -2
- data/spec/reek/{core → ast}/object_refs_spec.rb +3 -3
- data/spec/reek/{core → ast}/reference_collector_spec.rb +2 -2
- data/spec/reek/{sexp → ast}/sexp_extensions_spec.rb +6 -16
- data/spec/reek/{sexp → ast}/sexp_formatter_spec.rb +2 -2
- data/spec/reek/cli/option_interpreter_spec.rb +2 -1
- data/spec/reek/{core → cli}/warning_collector_spec.rb +3 -3
- data/spec/reek/{core/code_comment_spec.rb → code_comment_spec.rb} +3 -3
- data/spec/reek/configuration/app_configuration_spec.rb +31 -18
- data/spec/reek/{core → context}/code_context_spec.rb +14 -15
- data/spec/reek/{core → context}/method_context_spec.rb +8 -8
- data/spec/reek/{core → context}/module_context_spec.rb +4 -4
- data/spec/reek/context/root_context_spec.rb +14 -0
- data/spec/reek/{core → context}/singleton_method_context_spec.rb +4 -4
- data/spec/reek/{core/examiner_spec.rb → examiner_spec.rb} +3 -42
- data/spec/reek/{cli → report}/html_report_spec.rb +5 -5
- data/spec/reek/report/json_report_spec.rb +20 -0
- data/spec/reek/{cli → report}/text_report_spec.rb +14 -14
- data/spec/reek/{cli → report}/xml_report_spec.rb +7 -7
- data/spec/reek/report/yaml_report_spec.rb +20 -0
- data/spec/reek/smells/attribute_spec.rb +2 -1
- data/spec/reek/smells/boolean_parameter_spec.rb +1 -1
- data/spec/reek/smells/class_variable_spec.rb +5 -5
- data/spec/reek/smells/control_parameter_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +1 -1
- data/spec/reek/smells/duplicate_method_call_spec.rb +3 -3
- data/spec/reek/smells/feature_envy_spec.rb +1 -1
- data/spec/reek/smells/irresponsible_module_spec.rb +24 -28
- data/spec/reek/smells/long_parameter_list_spec.rb +2 -2
- data/spec/reek/smells/long_yield_list_spec.rb +2 -2
- data/spec/reek/smells/nested_iterators_spec.rb +1 -1
- data/spec/reek/smells/nil_check_spec.rb +2 -2
- data/spec/reek/smells/prima_donna_method_spec.rb +3 -3
- data/spec/reek/smells/repeated_conditional_spec.rb +6 -6
- data/spec/reek/{core → smells}/smell_configuration_spec.rb +4 -4
- data/spec/reek/smells/smell_detector_shared.rb +2 -2
- data/spec/reek/{core → smells}/smell_repository_spec.rb +5 -4
- data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smells/too_many_methods_spec.rb +4 -4
- data/spec/reek/smells/too_many_statements_spec.rb +2 -2
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +4 -4
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +2 -2
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +3 -3
- data/spec/reek/smells/utility_function_spec.rb +23 -1
- data/spec/reek/source/source_code_spec.rb +1 -1
- data/spec/reek/source/source_locator_spec.rb +30 -0
- data/spec/reek/spec/should_reek_of_spec.rb +0 -17
- data/spec/reek/spec/should_reek_spec.rb +0 -25
- data/spec/reek/tree_dresser_spec.rb +16 -0
- data/spec/reek/{core/tree_walker_spec.rb → tree_walker_spec.rb} +5 -5
- data/spec/samples/{simple_configuration.reek → configuration/simple_configuration.reek} +0 -0
- data/spec/samples/configuration/with_excluded_paths.reek +4 -0
- data/spec/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +5 -0
- data/spec/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +2 -0
- data/spec/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +6 -0
- data/spec/spec_helper.rb +6 -7
- data/tasks/develop.rake +2 -2
- metadata +71 -69
- data/lib/reek/cli/report/formatter.rb +0 -69
- data/lib/reek/cli/report/heading_formatter.rb +0 -45
- data/lib/reek/cli/report/location_formatter.rb +0 -34
- data/lib/reek/cli/report/report.rb +0 -191
- data/lib/reek/core/ast_node.rb +0 -38
- data/lib/reek/core/code_comment.rb +0 -37
- data/lib/reek/core/examiner.rb +0 -85
- data/lib/reek/core/tree_dresser.rb +0 -24
- data/lib/reek/core/tree_walker.rb +0 -180
- data/lib/reek/source/source_repository.rb +0 -43
- data/spec/reek/cli/json_report_spec.rb +0 -20
- data/spec/reek/cli/yaml_report_spec.rb +0 -20
- data/spec/reek/core/object_source_spec.rb +0 -18
- data/spec/reek/core/stop_context_spec.rb +0 -14
- data/spec/reek/core/tree_dresser_spec.rb +0 -16
@@ -1,8 +1,11 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
1
3
|
module Reek
|
2
4
|
module Source
|
3
5
|
#
|
4
6
|
# Finds Ruby source files in a filesystem.
|
5
7
|
#
|
8
|
+
# @api private
|
6
9
|
class SourceLocator
|
7
10
|
# Initialize with the paths we want to search.
|
8
11
|
#
|
@@ -14,24 +17,39 @@ module Reek
|
|
14
17
|
# Traverses all paths we initialized the SourceLocator with, finds
|
15
18
|
# all relevant ruby files and returns them as a list.
|
16
19
|
#
|
17
|
-
#
|
20
|
+
# @return [Array<File>] - Ruby files found
|
18
21
|
def sources
|
19
|
-
|
22
|
+
source_paths.map { |pathname| File.new(pathname) }
|
20
23
|
end
|
21
24
|
|
22
25
|
private
|
23
26
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
def source_paths
|
28
|
+
relevant_paths = []
|
29
|
+
@paths.map do |given_path|
|
30
|
+
print_no_such_file_error(given_path) && next unless path_exists?(given_path)
|
31
|
+
Find.find(given_path) do |path|
|
32
|
+
pathname = Pathname.new(path)
|
33
|
+
if pathname.directory?
|
34
|
+
exclude_path?(pathname) ? Find.prune : next
|
35
|
+
else
|
36
|
+
relevant_paths << pathname
|
37
|
+
end
|
33
38
|
end
|
34
|
-
end
|
39
|
+
end
|
40
|
+
relevant_paths.flatten.sort
|
41
|
+
end
|
42
|
+
|
43
|
+
def exclude_path?(pathname)
|
44
|
+
Configuration::AppConfiguration.exclude_paths.include? pathname.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def path_exists?(path)
|
48
|
+
Pathname.new(path).exist?
|
49
|
+
end
|
50
|
+
|
51
|
+
def print_no_such_file_error(path)
|
52
|
+
$stderr.puts "Error: No such file - #{path}"
|
35
53
|
end
|
36
54
|
end
|
37
55
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
-
require_relative '../
|
2
|
-
require_relative '../
|
1
|
+
require_relative '../examiner'
|
2
|
+
require_relative '../report/formatter'
|
3
3
|
|
4
4
|
module Reek
|
5
5
|
module Spec
|
6
6
|
#
|
7
7
|
# An rspec matcher that matches when the +actual+ has code smells.
|
8
8
|
#
|
9
|
+
# @api private
|
9
10
|
class ShouldReek # :nodoc:
|
10
11
|
def matches?(actual)
|
11
|
-
@examiner =
|
12
|
+
@examiner = Examiner.new(actual)
|
12
13
|
@examiner.smelly?
|
13
14
|
end
|
14
15
|
|
@@ -17,7 +18,7 @@ module Reek
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def failure_message_when_negated
|
20
|
-
rpt =
|
21
|
+
rpt = Report::Formatter.format_list(@examiner.smells)
|
21
22
|
"Expected no smells, but got:\n#{rpt}"
|
22
23
|
end
|
23
24
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative '../
|
1
|
+
require_relative '../examiner'
|
2
2
|
|
3
3
|
module Reek
|
4
4
|
module Spec
|
@@ -6,6 +6,7 @@ module Reek
|
|
6
6
|
# An rspec matcher that matches when the +actual+ has the specified
|
7
7
|
# code smell.
|
8
8
|
#
|
9
|
+
# @api private
|
9
10
|
class ShouldReekOf
|
10
11
|
def initialize(smell_category, smell_details = {})
|
11
12
|
@smell_category = normalize smell_category
|
@@ -13,7 +14,7 @@ module Reek
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def matches?(actual)
|
16
|
-
@examiner =
|
17
|
+
@examiner = Examiner.new(actual)
|
17
18
|
@all_smells = @examiner.smells
|
18
19
|
@all_smells.any? { |warning| warning.matches?(@smell_category, @smell_details) }
|
19
20
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require_relative '../
|
2
|
-
require_relative '../
|
1
|
+
require_relative '../examiner'
|
2
|
+
require_relative '../report/formatter'
|
3
3
|
|
4
4
|
module Reek
|
5
5
|
module Spec
|
@@ -7,9 +7,10 @@ module Reek
|
|
7
7
|
# An rspec matcher that matches when the +actual+ has the specified
|
8
8
|
# code smell and no others.
|
9
9
|
#
|
10
|
+
# @api private
|
10
11
|
class ShouldReekOnlyOf < ShouldReekOf
|
11
12
|
def matches?(actual)
|
12
|
-
matches_examiner?(
|
13
|
+
matches_examiner?(Examiner.new(actual))
|
13
14
|
end
|
14
15
|
|
15
16
|
def matches_examiner?(examiner)
|
@@ -20,7 +21,7 @@ module Reek
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def failure_message
|
23
|
-
rpt =
|
24
|
+
rpt = Report::Formatter.format_list(@warnings)
|
24
25
|
"Expected #{@examiner.description} to reek only of #{@smell_category}, but got:\n#{rpt}"
|
25
26
|
end
|
26
27
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'ast/ast_node_class_map'
|
2
|
+
|
3
|
+
module Reek
|
4
|
+
#
|
5
|
+
# Adorns an abstract syntax tree with mix-in modules to make accessing
|
6
|
+
# the tree more understandable and less implementation-dependent.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class TreeDresser
|
10
|
+
def initialize(klass_map = AST::ASTNodeClassMap.new)
|
11
|
+
@klass_map = klass_map
|
12
|
+
end
|
13
|
+
|
14
|
+
# Recursively enhance an AST with type-dependent mixins, and comments.
|
15
|
+
#
|
16
|
+
# See {file:docs/How-reek-works-internally.md} for the big picture of how this works.
|
17
|
+
#
|
18
|
+
# @param sexp [Parser::AST::Node] - the given sexp
|
19
|
+
# @param comment_map [Hash] - see the documentation for SourceCode#syntax_tree
|
20
|
+
# @param parent [Parser::AST::Node] - the parent sexp
|
21
|
+
#
|
22
|
+
# @return an instance of Reek::AST::Node with type-dependent sexp extensions mixed in.
|
23
|
+
def dress(sexp, comment_map, parent = nil)
|
24
|
+
return sexp unless sexp.is_a? ::Parser::AST::Node
|
25
|
+
type = sexp.type
|
26
|
+
children = sexp.children.map { |child| dress(child, comment_map, sexp) }
|
27
|
+
comments = comment_map[sexp]
|
28
|
+
@klass_map.klass_for(type).new(type, children,
|
29
|
+
location: sexp.loc, comments: comments, parent: parent)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require_relative 'context/method_context'
|
2
|
+
require_relative 'context/module_context'
|
3
|
+
require_relative 'context/root_context'
|
4
|
+
require_relative 'context/singleton_method_context'
|
5
|
+
require_relative 'smells/smell_repository'
|
6
|
+
require_relative 'ast/node'
|
7
|
+
|
8
|
+
module Reek
|
9
|
+
#
|
10
|
+
# Traverses a Sexp abstract syntax tree and fires events whenever
|
11
|
+
# it encounters specific node types.
|
12
|
+
#
|
13
|
+
# SMELL: This class is responsible for counting statements and for feeding
|
14
|
+
# each context to the smell repository.
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
class TreeWalker
|
18
|
+
def initialize(smell_repository = Smells::SmellRepository.new)
|
19
|
+
@smell_repository = smell_repository
|
20
|
+
@element = Context::RootContext.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def process(exp)
|
24
|
+
context_processor = "process_#{exp.type}"
|
25
|
+
if context_processor_exists?(context_processor)
|
26
|
+
send(context_processor, exp)
|
27
|
+
else
|
28
|
+
process_default exp
|
29
|
+
end
|
30
|
+
@element
|
31
|
+
end
|
32
|
+
|
33
|
+
def process_default(exp)
|
34
|
+
exp.children.each do |child|
|
35
|
+
process(child) if child.is_a? AST::Node
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def process_module(exp)
|
40
|
+
inside_new_context(Context::ModuleContext, exp) do
|
41
|
+
process_default(exp)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :process_class, :process_module
|
46
|
+
|
47
|
+
def process_def(exp)
|
48
|
+
inside_new_context(Context::MethodContext, exp) do
|
49
|
+
count_clause(exp.body)
|
50
|
+
process_default(exp)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_defs(exp)
|
55
|
+
inside_new_context(Context::SingletonMethodContext, exp) do
|
56
|
+
count_clause(exp.body)
|
57
|
+
process_default(exp)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def process_args(_) end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Recording of calls to methods and self
|
65
|
+
#
|
66
|
+
|
67
|
+
def process_send(exp)
|
68
|
+
@element.record_call_to(exp)
|
69
|
+
process_default(exp)
|
70
|
+
end
|
71
|
+
|
72
|
+
alias_method :process_attrasgn, :process_send
|
73
|
+
alias_method :process_op_asgn, :process_send
|
74
|
+
|
75
|
+
def process_ivar(exp)
|
76
|
+
@element.record_use_of_self
|
77
|
+
process_default(exp)
|
78
|
+
end
|
79
|
+
|
80
|
+
alias_method :process_ivasgn, :process_ivar
|
81
|
+
|
82
|
+
def process_self(_)
|
83
|
+
@element.record_use_of_self
|
84
|
+
end
|
85
|
+
|
86
|
+
alias_method :process_zsuper, :process_self
|
87
|
+
|
88
|
+
#
|
89
|
+
# Statement counting
|
90
|
+
#
|
91
|
+
|
92
|
+
def process_block(exp)
|
93
|
+
count_clause(exp.block)
|
94
|
+
process_default(exp)
|
95
|
+
end
|
96
|
+
|
97
|
+
def process_begin(exp)
|
98
|
+
count_statement_list(exp.children)
|
99
|
+
@element.count_statements(-1)
|
100
|
+
process_default(exp)
|
101
|
+
end
|
102
|
+
|
103
|
+
alias_method :process_kwbegin, :process_begin
|
104
|
+
|
105
|
+
def process_if(exp)
|
106
|
+
count_clause(exp[2])
|
107
|
+
count_clause(exp[3])
|
108
|
+
@element.count_statements(-1)
|
109
|
+
process_default(exp)
|
110
|
+
end
|
111
|
+
|
112
|
+
def process_while(exp)
|
113
|
+
count_clause(exp[2])
|
114
|
+
@element.count_statements(-1)
|
115
|
+
process_default(exp)
|
116
|
+
end
|
117
|
+
|
118
|
+
alias_method :process_until, :process_while
|
119
|
+
|
120
|
+
def process_for(exp)
|
121
|
+
count_clause(exp[3])
|
122
|
+
@element.count_statements(-1)
|
123
|
+
process_default(exp)
|
124
|
+
end
|
125
|
+
|
126
|
+
def process_rescue(exp)
|
127
|
+
count_clause(exp[1])
|
128
|
+
@element.count_statements(-1)
|
129
|
+
process_default(exp)
|
130
|
+
end
|
131
|
+
|
132
|
+
def process_resbody(exp)
|
133
|
+
count_statement_list(exp[2..-1].compact)
|
134
|
+
process_default(exp)
|
135
|
+
end
|
136
|
+
|
137
|
+
def process_case(exp)
|
138
|
+
count_clause(exp.else_body)
|
139
|
+
@element.count_statements(-1)
|
140
|
+
process_default(exp)
|
141
|
+
end
|
142
|
+
|
143
|
+
def process_when(exp)
|
144
|
+
count_clause(exp.body)
|
145
|
+
process_default(exp)
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def context_processor_exists?(name)
|
151
|
+
respond_to?(name)
|
152
|
+
end
|
153
|
+
|
154
|
+
def count_clause(sexp)
|
155
|
+
@element.count_statements(1) if sexp
|
156
|
+
end
|
157
|
+
|
158
|
+
def count_statement_list(statement_list)
|
159
|
+
@element.count_statements statement_list.length
|
160
|
+
end
|
161
|
+
|
162
|
+
def inside_new_context(klass, exp)
|
163
|
+
scope = klass.new(@element, exp)
|
164
|
+
push(scope) do
|
165
|
+
yield
|
166
|
+
check_smells(exp.type)
|
167
|
+
end
|
168
|
+
scope
|
169
|
+
end
|
170
|
+
|
171
|
+
def check_smells(type)
|
172
|
+
@smell_repository.examine(@element, type)
|
173
|
+
end
|
174
|
+
|
175
|
+
def push(scope)
|
176
|
+
orig = @element
|
177
|
+
@element = scope
|
178
|
+
yield
|
179
|
+
@element = orig
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
data/lib/reek/version.rb
CHANGED
data/reek.gemspec
CHANGED
@@ -19,20 +19,20 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = s.files.grep(%r{^bin/}).map { |path| File.basename(path) }
|
20
20
|
s.homepage = 'https://github.com/troessner/reek/wiki'
|
21
21
|
s.rdoc_options = %w(--main README.md -x assets/|bin/|config/|features/|spec/|tasks/)
|
22
|
-
s.required_ruby_version = '>=
|
22
|
+
s.required_ruby_version = '>= 2.0.0'
|
23
23
|
s.summary = 'Code smell detector for Ruby'
|
24
24
|
|
25
|
-
s.add_runtime_dependency 'parser', '~> 2.2'
|
25
|
+
s.add_runtime_dependency 'parser', '~> 2.2.2.5'
|
26
26
|
s.add_runtime_dependency 'rainbow', '~> 2.0'
|
27
27
|
s.add_runtime_dependency 'unparser', '~> 0.2.2'
|
28
28
|
|
29
29
|
s.add_development_dependency 'activesupport', '~> 4.2'
|
30
30
|
s.add_development_dependency 'aruba', '~> 0.6.2'
|
31
|
+
s.add_development_dependency 'ataru', '~> 0.2.0'
|
31
32
|
s.add_development_dependency 'bundler', '~> 1.1'
|
32
33
|
s.add_development_dependency 'cucumber', '~> 2.0'
|
33
34
|
s.add_development_dependency 'factory_girl', '~> 4.0'
|
34
35
|
s.add_development_dependency 'rake', '~> 10.0'
|
35
36
|
s.add_development_dependency 'rspec', '~> 3.0'
|
36
37
|
s.add_development_dependency 'rubocop', '~> 0.30.0'
|
37
|
-
s.add_development_dependency 'yard', '~> 0.8.7'
|
38
38
|
end
|
data/spec/factories/factories.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
|
-
require_relative '../../../lib/reek/
|
2
|
+
require_relative '../../../lib/reek/ast/node'
|
3
3
|
|
4
|
-
RSpec.describe Reek::
|
4
|
+
RSpec.describe Reek::AST::Node do
|
5
5
|
context 'format' do
|
6
6
|
it 'formats self' do
|
7
7
|
@node = s(:self)
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
|
-
require_relative '../../../lib/reek/
|
2
|
+
require_relative '../../../lib/reek/ast/object_refs'
|
3
3
|
|
4
|
-
RSpec.describe Reek::
|
4
|
+
RSpec.describe Reek::AST::ObjectRefs do
|
5
5
|
before(:each) do
|
6
|
-
@refs = Reek::
|
6
|
+
@refs = Reek::AST::ObjectRefs.new
|
7
7
|
end
|
8
8
|
|
9
9
|
context 'when empty' do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
|
-
require_relative '../../../lib/reek/
|
2
|
+
require_relative '../../../lib/reek/ast/reference_collector'
|
3
3
|
|
4
|
-
RSpec.describe Reek::
|
4
|
+
RSpec.describe Reek::AST::ReferenceCollector do
|
5
5
|
context 'counting refs to self' do
|
6
6
|
def refs_to_self(src)
|
7
7
|
syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
|
-
require_relative '../../../lib/reek/
|
2
|
+
require_relative '../../../lib/reek/ast/sexp_extensions'
|
3
3
|
|
4
|
-
RSpec.describe Reek::
|
4
|
+
RSpec.describe Reek::AST::SexpExtensions::DefNode do
|
5
5
|
context 'with no parameters' do
|
6
6
|
before :each do
|
7
7
|
@node = s(:def, :hello, s(:args))
|
@@ -108,11 +108,6 @@ RSpec.describe Reek::Sexp::SexpExtensions::DefNode do
|
|
108
108
|
expect(@node.body).to eq s(:begin, s(:first), s(:second))
|
109
109
|
end
|
110
110
|
|
111
|
-
it 'has a body extended with SexpNode' do
|
112
|
-
b = @node.body
|
113
|
-
expect(b.class.included_modules.first).to eq Reek::Sexp::SexpNode
|
114
|
-
end
|
115
|
-
|
116
111
|
it 'finds nodes in the body with #body_nodes' do
|
117
112
|
expect(@node.body_nodes([:first])).to eq [s(:first)]
|
118
113
|
end
|
@@ -133,7 +128,7 @@ RSpec.describe Reek::Sexp::SexpExtensions::DefNode do
|
|
133
128
|
end
|
134
129
|
end
|
135
130
|
|
136
|
-
RSpec.describe Reek::
|
131
|
+
RSpec.describe Reek::AST::SexpExtensions::DefsNode do
|
137
132
|
context 'with no parameters' do
|
138
133
|
before :each do
|
139
134
|
@node = s(:defs, s(:lvar, :obj), :hello, s(:args))
|
@@ -239,15 +234,10 @@ RSpec.describe Reek::Sexp::SexpExtensions::DefsNode do
|
|
239
234
|
it 'has 2 body statements' do
|
240
235
|
expect(@node.body).to eq s(:begin, s(:first), s(:second))
|
241
236
|
end
|
242
|
-
|
243
|
-
it 'has a body extended with SexpNode' do
|
244
|
-
b = @node.body
|
245
|
-
expect(b.class.included_modules.first).to eq Reek::Sexp::SexpNode
|
246
|
-
end
|
247
237
|
end
|
248
238
|
end
|
249
239
|
|
250
|
-
RSpec.describe Reek::
|
240
|
+
RSpec.describe Reek::AST::SexpExtensions::SendNode do
|
251
241
|
context 'with no parameters' do
|
252
242
|
before :each do
|
253
243
|
@node = s(:send, nil, :hello)
|
@@ -279,7 +269,7 @@ RSpec.describe Reek::Sexp::SexpExtensions::SendNode do
|
|
279
269
|
end
|
280
270
|
end
|
281
271
|
|
282
|
-
RSpec.describe Reek::
|
272
|
+
RSpec.describe Reek::AST::SexpExtensions::BlockNode do
|
283
273
|
context 'with no parameters' do
|
284
274
|
before :each do
|
285
275
|
@node = s(:block, s(:send, nil, :map), s(:args), nil)
|
@@ -311,7 +301,7 @@ RSpec.describe Reek::Sexp::SexpExtensions::BlockNode do
|
|
311
301
|
end
|
312
302
|
end
|
313
303
|
|
314
|
-
RSpec.describe Reek::
|
304
|
+
RSpec.describe Reek::AST::SexpExtensions::ModuleNode do
|
315
305
|
context 'with a simple name' do
|
316
306
|
subject do
|
317
307
|
mod = ast(:module, :Fred, nil)
|