reek 4.5.0 → 4.6.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 +10 -7
- data/.travis.yml +13 -9
- data/CHANGELOG.md +36 -3
- data/Dockerfile +6 -5
- data/Gemfile +8 -7
- data/README.md +45 -27
- data/docs/How-To-Write-New-Detectors.md +6 -6
- data/docs/Irresponsible-Module.md +8 -1
- data/docs/Nil-Check.md +1 -1
- data/docs/Prima-Donna-Method.md +27 -0
- data/docs/RSpec-matchers.md +5 -10
- data/docs/Unused-Private-Method.md +27 -0
- data/docs/templates/default/docstring/setup.rb +1 -8
- data/features/command_line_interface/options.feature +5 -1
- data/features/command_line_interface/stdin.feature +1 -1
- data/features/configuration_files/exclude_paths_directives.feature +43 -0
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +44 -0
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +15 -0
- data/features/samples.feature +3 -8
- data/features/step_definitions/reek_steps.rb +5 -5
- data/features/todo_list.feature +1 -2
- data/lib/reek/ast/reference_collector.rb +2 -4
- data/lib/reek/ast/sexp_extensions/arguments.rb +0 -5
- data/lib/reek/ast/sexp_extensions/constant.rb +1 -0
- data/lib/reek/cli/application.rb +7 -8
- data/lib/reek/cli/command/report_command.rb +3 -1
- data/lib/reek/cli/options.rb +29 -13
- data/lib/reek/cli/status.rb +10 -0
- data/lib/reek/code_comment.rb +48 -6
- data/lib/reek/configuration/configuration_file_finder.rb +87 -27
- data/lib/reek/context/ghost_context.rb +1 -2
- data/lib/reek/context_builder.rb +26 -1
- data/lib/reek/detector_repository.rb +64 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +37 -0
- data/lib/reek/errors/bad_detector_in_comment_error.rb +2 -1
- data/lib/reek/errors/base_error.rb +9 -0
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +2 -1
- data/lib/reek/errors/incomprehensible_source_error.rb +47 -0
- data/lib/reek/errors/parse_error.rb +19 -0
- data/lib/reek/examiner.rb +17 -41
- data/lib/reek/logging_error_handler.rb +15 -0
- data/lib/reek/report/code_climate/code_climate_configuration.rb +12 -0
- data/lib/reek/report/code_climate/code_climate_configuration.yml +156 -0
- data/lib/reek/report/code_climate/code_climate_fingerprint.rb +4 -2
- data/lib/reek/report/code_climate/code_climate_formatter.rb +2 -2
- data/lib/reek/smell_configuration.rb +64 -0
- data/lib/reek/smell_detectors/attribute.rb +0 -2
- data/lib/reek/smell_detectors/base_detector.rb +24 -4
- data/lib/reek/smell_detectors/boolean_parameter.rb +0 -1
- data/lib/reek/smell_detectors/class_variable.rb +0 -1
- data/lib/reek/smell_detectors/control_parameter.rb +0 -1
- data/lib/reek/smell_detectors/data_clump.rb +0 -1
- data/lib/reek/smell_detectors/duplicate_method_call.rb +0 -1
- data/lib/reek/smell_detectors/feature_envy.rb +0 -1
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +0 -1
- data/lib/reek/smell_detectors/irresponsible_module.rb +0 -1
- data/lib/reek/smell_detectors/long_parameter_list.rb +0 -2
- data/lib/reek/smell_detectors/long_yield_list.rb +0 -1
- data/lib/reek/smell_detectors/manual_dispatch.rb +4 -6
- data/lib/reek/smell_detectors/module_initialize.rb +5 -8
- data/lib/reek/smell_detectors/nested_iterators.rb +0 -1
- data/lib/reek/smell_detectors/nil_check.rb +0 -1
- data/lib/reek/smell_detectors/prima_donna_method.rb +30 -1
- data/lib/reek/smell_detectors/repeated_conditional.rb +0 -1
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +0 -1
- data/lib/reek/smell_detectors/too_many_constants.rb +0 -1
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +0 -1
- data/lib/reek/smell_detectors/too_many_methods.rb +0 -1
- data/lib/reek/smell_detectors/too_many_statements.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +0 -1
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +0 -1
- data/lib/reek/smell_detectors/unused_parameters.rb +0 -1
- data/lib/reek/smell_detectors/unused_private_method.rb +0 -2
- data/lib/reek/smell_detectors/utility_function.rb +0 -1
- data/lib/reek/smell_warning.rb +85 -0
- data/lib/reek/source/source_code.rb +2 -1
- data/lib/reek/source/source_locator.rb +15 -3
- data/lib/reek/spec/should_reek_of.rb +1 -1
- data/lib/reek/spec.rb +6 -4
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +1 -1
- data/samples/configuration/more_than_one_configuration_file/todo.reek +0 -0
- data/samples/configuration/single_configuration_file/.reek +0 -0
- data/spec/factories/factories.rb +2 -10
- data/spec/quality/reek_source_spec.rb +5 -3
- data/spec/reek/ast/reference_collector_spec.rb +0 -17
- data/spec/reek/cli/application_spec.rb +25 -1
- data/spec/reek/cli/command/report_command_spec.rb +2 -2
- data/spec/reek/cli/command/todo_list_command_spec.rb +14 -71
- data/spec/reek/cli/options_spec.rb +4 -0
- data/spec/reek/code_comment_spec.rb +47 -0
- data/spec/reek/configuration/configuration_file_finder_spec.rb +38 -15
- data/spec/reek/context/code_context_spec.rb +10 -10
- data/spec/reek/context/method_context_spec.rb +1 -1
- data/spec/reek/context/module_context_spec.rb +8 -4
- data/spec/reek/{smell_detectors/detector_repository_spec.rb → detector_repository_spec.rb} +3 -3
- data/spec/reek/examiner_spec.rb +39 -40
- data/spec/reek/logging_error_handler_spec.rb +24 -0
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +24 -0
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +9 -9
- data/spec/reek/report/yaml_report_spec.rb +4 -4
- data/spec/reek/{smell_detectors/smell_configuration_spec.rb → smell_configuration_spec.rb} +3 -3
- data/spec/reek/smell_detectors/base_detector_spec.rb +18 -0
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +2 -2
- data/spec/reek/smell_detectors/feature_envy_spec.rb +18 -8
- data/spec/reek/smell_detectors/manual_dispatch_spec.rb +13 -0
- data/spec/reek/smell_detectors/module_initialize_spec.rb +23 -2
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
- data/spec/reek/smell_detectors/prima_donna_method_spec.rb +12 -0
- data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -5
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +2 -2
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +1 -1
- data/spec/reek/{smell_detectors/smell_warning_spec.rb → smell_warning_spec.rb} +9 -9
- data/spec/reek/source/source_code_spec.rb +6 -29
- data/spec/reek/source/source_locator_spec.rb +48 -16
- data/spec/reek/spec/should_reek_of_spec.rb +1 -1
- data/spec/reek/spec/should_reek_only_of_spec.rb +4 -4
- data/spec/spec_helper.rb +4 -3
- data/tasks/configuration.rake +2 -2
- metadata +26 -14
- data/lib/reek/smell_detectors/detector_repository.rb +0 -66
- data/lib/reek/smell_detectors/smell_configuration.rb +0 -66
- data/lib/reek/smell_detectors/smell_warning.rb +0 -88
- data/tasks/mutant.rake +0 -14
- /data/samples/configuration/{.reek → more_than_one_configuration_file/regular.reek} +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require_relative 'base_detector'
|
|
3
|
-
require_relative 'smell_warning'
|
|
4
3
|
|
|
5
4
|
module Reek
|
|
6
5
|
module SmellDetectors
|
|
@@ -21,11 +20,10 @@ module Reek
|
|
|
21
20
|
#
|
|
22
21
|
# :reek:FeatureEnvy
|
|
23
22
|
def sniff(ctx)
|
|
24
|
-
ctx.each_node(:send).
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end.compact
|
|
23
|
+
smelly_nodes = ctx.each_node(:send).select { |node| node.name == :respond_to? }
|
|
24
|
+
return [] if smelly_nodes.empty?
|
|
25
|
+
lines = smelly_nodes.map(&:line)
|
|
26
|
+
[smell_warning(context: ctx, lines: lines, message: MESSAGE)]
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require_relative 'base_detector'
|
|
3
|
-
require_relative 'smell_warning'
|
|
4
3
|
|
|
5
4
|
module Reek
|
|
6
5
|
module SmellDetectors
|
|
@@ -23,13 +22,11 @@ module Reek
|
|
|
23
22
|
# :reek:FeatureEnvy
|
|
24
23
|
def sniff(ctx)
|
|
25
24
|
ctx.local_nodes(:def) do |node|
|
|
26
|
-
if node.name
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
message: 'has initialize method')
|
|
32
|
-
]
|
|
25
|
+
if node.name == :initialize
|
|
26
|
+
return smell_warning(
|
|
27
|
+
context: ctx,
|
|
28
|
+
lines: [ctx.exp.line],
|
|
29
|
+
message: 'has initialize method')
|
|
33
30
|
end
|
|
34
31
|
end
|
|
35
32
|
[]
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require_relative 'base_detector'
|
|
3
|
-
require_relative 'smell_warning'
|
|
4
3
|
|
|
5
4
|
module Reek
|
|
6
5
|
module SmellDetectors
|
|
@@ -29,6 +28,24 @@ module Reek
|
|
|
29
28
|
[:class]
|
|
30
29
|
end
|
|
31
30
|
|
|
31
|
+
#
|
|
32
|
+
# @param ctx [Context::ModuleContext]
|
|
33
|
+
# @return [Array<SmellWarning>]
|
|
34
|
+
#
|
|
35
|
+
# Given this code:
|
|
36
|
+
#
|
|
37
|
+
# class Alfa
|
|
38
|
+
# def bravo!
|
|
39
|
+
# end
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# An example `ctx` could look like this:
|
|
43
|
+
#
|
|
44
|
+
# s(:class,
|
|
45
|
+
# s(:const, nil, :Alfa), nil,
|
|
46
|
+
# s(:def, :bravo!,
|
|
47
|
+
# s(:args), nil))
|
|
48
|
+
#
|
|
32
49
|
def sniff(ctx)
|
|
33
50
|
ctx.node_instance_methods.select do |method_sexp|
|
|
34
51
|
prima_donna_method?(method_sexp, ctx)
|
|
@@ -46,6 +63,7 @@ module Reek
|
|
|
46
63
|
|
|
47
64
|
def prima_donna_method?(method_sexp, ctx)
|
|
48
65
|
return false unless method_sexp.ends_with_bang?
|
|
66
|
+
return false if ignore_method?(method_sexp, ctx)
|
|
49
67
|
return false if version_without_bang_exists?(method_sexp, ctx)
|
|
50
68
|
true
|
|
51
69
|
end
|
|
@@ -56,6 +74,17 @@ module Reek
|
|
|
56
74
|
sexp_item.name.to_s == method_sexp.name_without_bang
|
|
57
75
|
end
|
|
58
76
|
end
|
|
77
|
+
|
|
78
|
+
#
|
|
79
|
+
# @param method_node [Reek::AST::Node],
|
|
80
|
+
# e.g. s(:def, :bravo!, s(:args), nil)
|
|
81
|
+
# @param ctx [Context::ModuleContext]
|
|
82
|
+
# @return [Boolean]
|
|
83
|
+
#
|
|
84
|
+
def ignore_method?(method_node, ctx)
|
|
85
|
+
ignore_method_names = value(EXCLUDE_KEY, ctx) # e.g. ["bravo!"]
|
|
86
|
+
ignore_method_names.include? method_node.name.to_s # method_node.name is e.g.: :bravo!
|
|
87
|
+
end
|
|
59
88
|
end
|
|
60
89
|
end
|
|
61
90
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module Reek
|
|
5
|
+
#
|
|
6
|
+
# Reports a warning that a smell has been found.
|
|
7
|
+
#
|
|
8
|
+
# @public
|
|
9
|
+
#
|
|
10
|
+
# :reek:TooManyInstanceVariables: { max_instance_variables: 6 }
|
|
11
|
+
class SmellWarning
|
|
12
|
+
include Comparable
|
|
13
|
+
extend Forwardable
|
|
14
|
+
|
|
15
|
+
# @public
|
|
16
|
+
attr_reader :context, :lines, :message, :parameters, :smell_detector, :source
|
|
17
|
+
def_delegators :smell_detector, :smell_type
|
|
18
|
+
|
|
19
|
+
# @note When using Reek's public API, you should not create SmellWarning
|
|
20
|
+
# objects yourself. This is why the initializer is not part of the
|
|
21
|
+
# public API.
|
|
22
|
+
#
|
|
23
|
+
# :reek:LongParameterList: { max_params: 6 }
|
|
24
|
+
def initialize(smell_detector, context: '', lines:, message:,
|
|
25
|
+
source:, parameters: {})
|
|
26
|
+
@smell_detector = smell_detector
|
|
27
|
+
@source = source
|
|
28
|
+
@context = context.to_s
|
|
29
|
+
@lines = lines
|
|
30
|
+
@message = message
|
|
31
|
+
@parameters = parameters
|
|
32
|
+
|
|
33
|
+
freeze
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @public
|
|
37
|
+
def hash
|
|
38
|
+
identifying_values.hash
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @public
|
|
42
|
+
def <=>(other)
|
|
43
|
+
identifying_values <=> other.identifying_values
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @public
|
|
47
|
+
def eql?(other)
|
|
48
|
+
(self <=> other).zero?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @public
|
|
52
|
+
def to_hash
|
|
53
|
+
stringified_params = Hash[parameters.map { |key, val| [key.to_s, val] }]
|
|
54
|
+
base_hash.merge(stringified_params)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
alias yaml_hash to_hash
|
|
58
|
+
|
|
59
|
+
def base_message
|
|
60
|
+
"#{smell_type}: #{context} #{message}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def smell_class
|
|
64
|
+
smell_detector.class
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
protected
|
|
68
|
+
|
|
69
|
+
def identifying_values
|
|
70
|
+
[smell_type, context, message, lines]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def base_hash
|
|
76
|
+
{
|
|
77
|
+
'context' => context,
|
|
78
|
+
'lines' => lines,
|
|
79
|
+
'message' => message,
|
|
80
|
+
'smell_type' => smell_type,
|
|
81
|
+
'source' => source
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -5,6 +5,7 @@ Reek::CLI::Silencer.silently do
|
|
|
5
5
|
end
|
|
6
6
|
require_relative '../tree_dresser'
|
|
7
7
|
require_relative '../ast/node'
|
|
8
|
+
require_relative '../errors/parse_error'
|
|
8
9
|
|
|
9
10
|
# Opt in to new way of representing lambdas
|
|
10
11
|
Parser::Builders::Default.emit_lambda = true
|
|
@@ -87,7 +88,7 @@ module Reek
|
|
|
87
88
|
begin
|
|
88
89
|
ast, comments = parser.parse_with_comments(source, origin)
|
|
89
90
|
rescue Racc::ParseError, Parser::SyntaxError => error
|
|
90
|
-
|
|
91
|
+
raise Errors::ParseError, origin: origin, original_exception: error
|
|
91
92
|
end
|
|
92
93
|
|
|
93
94
|
# See https://whitequark.github.io/parser/Parser/Source/Comment/Associator.html
|
|
@@ -11,7 +11,8 @@ module Reek
|
|
|
11
11
|
# Initialize with the paths we want to search.
|
|
12
12
|
#
|
|
13
13
|
# paths - a list of paths as Strings
|
|
14
|
-
def initialize(paths, configuration: Configuration::AppConfiguration.default)
|
|
14
|
+
def initialize(paths, configuration: Configuration::AppConfiguration.default, options: Reek::CLI::Options.new)
|
|
15
|
+
@options = options
|
|
15
16
|
@paths = paths.flat_map do |string|
|
|
16
17
|
path = Pathname.new(string)
|
|
17
18
|
current_directory?(path) ? path.entries : path
|
|
@@ -29,7 +30,7 @@ module Reek
|
|
|
29
30
|
|
|
30
31
|
private
|
|
31
32
|
|
|
32
|
-
attr_reader :configuration, :paths
|
|
33
|
+
attr_reader :configuration, :paths, :options
|
|
33
34
|
|
|
34
35
|
# :reek:TooManyStatements: { max_statements: 7 }
|
|
35
36
|
# :reek:NestedIterators: { max_allowed_nesting: 2 }
|
|
@@ -44,12 +45,23 @@ module Reek
|
|
|
44
45
|
if path.directory?
|
|
45
46
|
ignore_path?(path) ? Find.prune : next
|
|
46
47
|
elsif ruby_file?(path)
|
|
47
|
-
relevant_paths << path
|
|
48
|
+
relevant_paths << path unless ignore_file?(path)
|
|
48
49
|
end
|
|
49
50
|
end
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
|
|
54
|
+
def ignore_file?(path)
|
|
55
|
+
if options.force_exclusion?
|
|
56
|
+
path.ascend do |ascendant|
|
|
57
|
+
break true if path_excluded?(ascendant)
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
53
65
|
def path_excluded?(path)
|
|
54
66
|
configuration.path_excluded?(path)
|
|
55
67
|
end
|
|
@@ -25,7 +25,7 @@ module Reek
|
|
|
25
25
|
configuration = Configuration::AppConfiguration.default)
|
|
26
26
|
@smell_type = normalize smell_type_or_class
|
|
27
27
|
@smell_details = smell_details
|
|
28
|
-
configuration.load_values(smell_type => {
|
|
28
|
+
configuration.load_values(smell_type => { SmellConfiguration::ENABLED_KEY => true })
|
|
29
29
|
@configuration = configuration
|
|
30
30
|
end
|
|
31
31
|
|
data/lib/reek/spec.rb
CHANGED
|
@@ -48,10 +48,10 @@ module Reek
|
|
|
48
48
|
# Checks the target source code for instances of "smell type"
|
|
49
49
|
# and returns true only if it can find one of them that matches.
|
|
50
50
|
#
|
|
51
|
-
# You
|
|
51
|
+
# You can pass the smell type you want to check for as String or as Symbol:
|
|
52
|
+
#
|
|
52
53
|
# - :UtilityFunction
|
|
53
54
|
# - "UtilityFunction"
|
|
54
|
-
# - Reek::Smells::UtilityFunction
|
|
55
55
|
#
|
|
56
56
|
# It is recommended to pass this as a symbol like :UtilityFunction. However we don't
|
|
57
57
|
# enforce this.
|
|
@@ -70,7 +70,7 @@ module Reek
|
|
|
70
70
|
# @example Without smell_details
|
|
71
71
|
#
|
|
72
72
|
# reek_of(:FeatureEnvy)
|
|
73
|
-
# reek_of(
|
|
73
|
+
# reek_of(:UtilityFunction)
|
|
74
74
|
#
|
|
75
75
|
# @example With smell_details
|
|
76
76
|
#
|
|
@@ -79,7 +79,7 @@ module Reek
|
|
|
79
79
|
#
|
|
80
80
|
# @example From a real spec
|
|
81
81
|
#
|
|
82
|
-
# expect(src).to reek_of(
|
|
82
|
+
# expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing')
|
|
83
83
|
#
|
|
84
84
|
# @public
|
|
85
85
|
#
|
|
@@ -98,6 +98,8 @@ module Reek
|
|
|
98
98
|
# "reek_only_of" will fail in that case.
|
|
99
99
|
# 2.) "reek_only_of" doesn't support the additional smell_details hash.
|
|
100
100
|
#
|
|
101
|
+
# @param smell_type [Symbol, String, Class] The "smell type" to check for.
|
|
102
|
+
#
|
|
101
103
|
# @public
|
|
102
104
|
#
|
|
103
105
|
# :reek:UtilityFunction
|
data/lib/reek/version.rb
CHANGED
data/reek.gemspec
CHANGED
|
@@ -22,6 +22,6 @@ Gem::Specification.new do |s|
|
|
|
22
22
|
s.summary = 'Code smell detector for Ruby'
|
|
23
23
|
|
|
24
24
|
s.add_runtime_dependency 'codeclimate-engine-rb', '~> 0.4.0'
|
|
25
|
-
s.add_runtime_dependency 'parser', '
|
|
25
|
+
s.add_runtime_dependency 'parser', '< 2.5', '>= 2.3.1.2'
|
|
26
26
|
s.add_runtime_dependency 'rainbow', '~> 2.0'
|
|
27
27
|
end
|
|
File without changes
|
|
File without changes
|
data/spec/factories/factories.rb
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
require_relative '../../lib/reek/smell_detectors'
|
|
2
2
|
require_relative '../../lib/reek/smell_detectors/base_detector'
|
|
3
|
-
require_relative '../../lib/reek/
|
|
3
|
+
require_relative '../../lib/reek/smell_warning'
|
|
4
4
|
require_relative '../../lib/reek/cli/options'
|
|
5
5
|
|
|
6
6
|
FactoryGirl.define do
|
|
7
|
-
factory :context, class: Reek::Context::CodeContext do
|
|
8
|
-
skip_create
|
|
9
|
-
|
|
10
|
-
initialize_with do
|
|
11
|
-
new(nil, nil)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
7
|
factory :method_context, class: Reek::Context::MethodContext do
|
|
16
8
|
skip_create
|
|
17
9
|
transient do
|
|
@@ -34,7 +26,7 @@ FactoryGirl.define do
|
|
|
34
26
|
end
|
|
35
27
|
end
|
|
36
28
|
|
|
37
|
-
factory :smell_warning, class: Reek::
|
|
29
|
+
factory :smell_warning, class: Reek::SmellWarning do
|
|
38
30
|
skip_create
|
|
39
31
|
smell_detector
|
|
40
32
|
context 'self'
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
require_relative '../spec_helper'
|
|
2
2
|
|
|
3
3
|
RSpec.describe 'Reek source code' do
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Pathname.glob('lib/**/*.rb').each do |pathname|
|
|
5
|
+
describe pathname do
|
|
6
|
+
it 'has no smells' do
|
|
7
|
+
expect(pathname).not_to reek
|
|
8
|
+
end
|
|
7
9
|
end
|
|
8
10
|
end
|
|
9
11
|
end
|
|
@@ -43,22 +43,5 @@ RSpec.describe Reek::AST::ReferenceCollector do
|
|
|
43
43
|
it 'ignores global variables' do
|
|
44
44
|
expect(refs_to_self('def no_envy(arga) $s2.to_a; $s2[arga] end')).to eq(0)
|
|
45
45
|
end
|
|
46
|
-
|
|
47
|
-
it 'ignores global variables' do
|
|
48
|
-
src = <<-EOS
|
|
49
|
-
def accept(t, pat = /.*/nm, &block)
|
|
50
|
-
if pat
|
|
51
|
-
pat.respond_to?(:match) or raise TypeError, "has no `match'"
|
|
52
|
-
else
|
|
53
|
-
pat = t if t.respond_to?(:match)
|
|
54
|
-
end
|
|
55
|
-
unless block
|
|
56
|
-
block = pat.method(:convert).to_proc if pat.respond_to?(:convert)
|
|
57
|
-
end
|
|
58
|
-
@atype[t] = [pat, block]
|
|
59
|
-
end
|
|
60
|
-
EOS
|
|
61
|
-
expect(refs_to_self(src)).to eq(2)
|
|
62
|
-
end
|
|
63
46
|
end
|
|
64
47
|
end
|
|
@@ -10,7 +10,7 @@ RSpec.describe Reek::CLI::Application do
|
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
expect(call).to raise_error(SystemExit) do |error|
|
|
13
|
-
expect(error.status).to eq Reek::CLI::
|
|
13
|
+
expect(error.status).to eq Reek::CLI::Status::DEFAULT_ERROR_EXIT_CODE
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
|
@@ -100,6 +100,30 @@ RSpec.describe Reek::CLI::Application do
|
|
|
100
100
|
configuration: Reek::Configuration::AppConfiguration,
|
|
101
101
|
options: Reek::CLI::Options)
|
|
102
102
|
end
|
|
103
|
+
|
|
104
|
+
context 'when source files are excluded through configuration' do
|
|
105
|
+
let(:app) { described_class.new ['--config', 'some_file.reek', '.'] }
|
|
106
|
+
|
|
107
|
+
before do
|
|
108
|
+
allow(Reek::Configuration::AppConfiguration).
|
|
109
|
+
to receive(:from_path).
|
|
110
|
+
with(Pathname.new('some_file.reek')).
|
|
111
|
+
and_return configuration
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'uses configuration for excluded paths' do
|
|
115
|
+
expected_sources = Reek::Source::SourceLocator.
|
|
116
|
+
new(['.'], configuration: configuration).sources
|
|
117
|
+
expect(expected_sources).not_to include(path_excluded_in_configuration)
|
|
118
|
+
|
|
119
|
+
app.execute
|
|
120
|
+
|
|
121
|
+
expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
|
|
122
|
+
with(sources: expected_sources,
|
|
123
|
+
configuration: configuration,
|
|
124
|
+
options: Reek::CLI::Options)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
103
127
|
end
|
|
104
128
|
end
|
|
105
129
|
end
|
|
@@ -26,7 +26,7 @@ RSpec.describe Reek::CLI::Command::ReportCommand do
|
|
|
26
26
|
result = Reek::CLI::Silencer.silently do
|
|
27
27
|
command.execute
|
|
28
28
|
end
|
|
29
|
-
expect(result).to eq Reek::CLI::
|
|
29
|
+
expect(result).to eq Reek::CLI::Status::DEFAULT_SUCCESS_EXIT_CODE
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@ RSpec.describe Reek::CLI::Command::ReportCommand do
|
|
|
37
37
|
result = Reek::CLI::Silencer.silently do
|
|
38
38
|
command.execute
|
|
39
39
|
end
|
|
40
|
-
expect(result).to eq Reek::CLI::
|
|
40
|
+
expect(result).to eq Reek::CLI::Status::DEFAULT_FAILURE_EXIT_CODE
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
end
|