reek 3.4.0 → 3.4.1

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/features/step_definitions/reek_steps.rb +19 -16
  4. data/lib/reek/ast/sexp_extensions.rb +17 -8
  5. data/lib/reek/cli/application.rb +21 -12
  6. data/lib/reek/cli/option_interpreter.rb +1 -6
  7. data/lib/reek/cli/options.rb +32 -22
  8. data/lib/reek/report/location_formatter.rb +11 -5
  9. data/lib/reek/smells/smell_warning.rb +10 -2
  10. data/lib/reek/smells/uncommunicative_method_name.rb +25 -21
  11. data/lib/reek/smells/uncommunicative_parameter_name.rb +14 -15
  12. data/lib/reek/spec/should_reek_of.rb +44 -9
  13. data/lib/reek/version.rb +1 -1
  14. data/reek.gemspec +2 -2
  15. data/spec/reek/ast/node_spec.rb +1 -1
  16. data/spec/reek/ast/object_refs_spec.rb +1 -1
  17. data/spec/reek/ast/reference_collector_spec.rb +1 -1
  18. data/spec/reek/ast/sexp_extensions_spec.rb +49 -2
  19. data/spec/reek/ast/sexp_formatter_spec.rb +1 -1
  20. data/spec/reek/cli/option_interpreter_spec.rb +7 -7
  21. data/spec/reek/cli/options_spec.rb +27 -19
  22. data/spec/reek/cli/warning_collector_spec.rb +2 -2
  23. data/spec/reek/code_comment_spec.rb +1 -1
  24. data/spec/reek/configuration/app_configuration_spec.rb +4 -4
  25. data/spec/reek/configuration/default_directive_spec.rb +1 -1
  26. data/spec/reek/configuration/directory_directives_spec.rb +1 -1
  27. data/spec/reek/configuration/excluded_paths_spec.rb +1 -1
  28. data/spec/reek/context/code_context_spec.rb +2 -2
  29. data/spec/reek/context/method_context_spec.rb +1 -1
  30. data/spec/reek/context/module_context_spec.rb +2 -2
  31. data/spec/reek/context/root_context_spec.rb +1 -1
  32. data/spec/reek/context/singleton_method_context_spec.rb +1 -1
  33. data/spec/reek/examiner_spec.rb +1 -1
  34. data/spec/reek/report/html_report_spec.rb +2 -2
  35. data/spec/reek/report/json_report_spec.rb +3 -3
  36. data/spec/reek/report/location_formatter_spec.rb +30 -0
  37. data/spec/reek/report/text_report_spec.rb +4 -4
  38. data/spec/reek/report/xml_report_spec.rb +2 -2
  39. data/spec/reek/report/yaml_report_spec.rb +3 -3
  40. data/spec/reek/smells/attribute_spec.rb +1 -1
  41. data/spec/reek/smells/boolean_parameter_spec.rb +1 -1
  42. data/spec/reek/smells/class_variable_spec.rb +2 -2
  43. data/spec/reek/smells/control_parameter_spec.rb +1 -1
  44. data/spec/reek/smells/data_clump_spec.rb +1 -1
  45. data/spec/reek/smells/duplicate_method_call_spec.rb +3 -3
  46. data/spec/reek/smells/feature_envy_spec.rb +2 -2
  47. data/spec/reek/smells/irresponsible_module_spec.rb +2 -2
  48. data/spec/reek/smells/long_parameter_list_spec.rb +2 -2
  49. data/spec/reek/smells/long_yield_list_spec.rb +2 -2
  50. data/spec/reek/smells/module_initialize_spec.rb +1 -1
  51. data/spec/reek/smells/nested_iterators_spec.rb +1 -1
  52. data/spec/reek/smells/nil_check_spec.rb +2 -2
  53. data/spec/reek/smells/prima_donna_method_spec.rb +1 -1
  54. data/spec/reek/smells/repeated_conditional_spec.rb +3 -3
  55. data/spec/reek/smells/smell_configuration_spec.rb +1 -1
  56. data/spec/reek/smells/smell_repository_spec.rb +2 -2
  57. data/spec/reek/smells/smell_warning_spec.rb +1 -1
  58. data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
  59. data/spec/reek/smells/too_many_methods_spec.rb +1 -1
  60. data/spec/reek/smells/too_many_statements_spec.rb +1 -1
  61. data/spec/reek/smells/uncommunicative_method_name_spec.rb +2 -2
  62. data/spec/reek/smells/uncommunicative_module_name_spec.rb +2 -2
  63. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +2 -2
  64. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
  65. data/spec/reek/smells/unused_parameters_spec.rb +1 -1
  66. data/spec/reek/smells/utility_function_spec.rb +2 -2
  67. data/spec/reek/source/source_code_spec.rb +1 -1
  68. data/spec/reek/source/source_locator_spec.rb +2 -2
  69. data/spec/reek/spec/should_reek_of_spec.rb +90 -37
  70. data/spec/reek/spec/should_reek_only_of_spec.rb +1 -1
  71. data/spec/reek/spec/should_reek_spec.rb +1 -1
  72. data/spec/reek/tree_dresser_spec.rb +2 -2
  73. data/spec/reek/tree_walker_spec.rb +2 -2
  74. data/spec/spec_helper.rb +6 -0
  75. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c8492565566dc33ddd04e6474399de644c050c31
4
- data.tar.gz: 40d22b046c4c8a9be279dae6aacd3859d7534d46
3
+ metadata.gz: 846eb328f05e66b28b63cb9103b710d75a61a98b
4
+ data.tar.gz: f870a86b912aca22b1720902098afeb575de4a03
5
5
  SHA512:
6
- metadata.gz: e929fb9f9a89fddb7383ed8fd606b22f31977ed43360160a3359cb325b7a56adbd4801ba7ded8993f90aae42f7369cda18be10b1ff2d44ed9181a2711affea84
7
- data.tar.gz: ece84cae1ab3d23b457f7f31f6ce47ba48ea65683a82291645803020b418609137fbe5eae6185d1e706ae840a3cbc87a27de4d6abbbef624177cfc13373947e2
6
+ metadata.gz: b2ee82efb561b2270381528407b1488b695c24f954e78688999df29b3dc17246faa473b523454a7a1c0e65e8aea4201270786a3df2e251ef57f2760ea924228e
7
+ data.tar.gz: a80ad9e5f23f1e5db3d5e8df22d55e8cf17656a028582ce25af3d2c00c9bde74002a13f97724ef09c7ea12205e3b0ab0c3ee9a2612aad8fb346ef12f2d4c918f
@@ -2,6 +2,15 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 3.4.1 (2015-09-24)
6
+
7
+ * (chastell) Fix parsing `Foo = bar.new(new)`
8
+ * (chastell) Sort line numbers in reports of multi-line smells
9
+ * (chastell) Fix parsing bare `attr`
10
+ * (troessner) Fix `reek_of` not checking `smell_details`
11
+ * (chastell) Fix parsing `Foo = new`
12
+ * (chastell) Fix parsing `Foo = Class.new do … end.new`
13
+
5
14
  ## 3.4.0 (2015-09-16)
6
15
 
7
16
  * (troessner) Make UtilityFunction configurable for non-public methods
@@ -11,69 +11,72 @@ When /^I run rake (\w*) with:$/ do |name, task_def|
11
11
  end
12
12
 
13
13
  Then /^it reports nothing$/ do
14
- assert_exact_output '', all_stdout
14
+ expect(last_command_started).to have_output_on_stdout('')
15
15
  end
16
16
 
17
17
  Then /^there is no output on stdout$/ do
18
- assert_exact_output '', all_stdout
18
+ expect(last_command_started).to have_output_on_stdout('')
19
19
  end
20
20
 
21
21
  Then /^stdout includes "(.*)"$/ do |text|
22
- assert_partial_output(text, all_stdout)
22
+ expect(last_command_started).to have_output_on_stdout(/#{Regexp.escape(text)}/)
23
23
  end
24
24
 
25
25
  Then /^it succeeds$/ do
26
- assert_exit_status Reek::CLI::Application::STATUS_SUCCESS
26
+ success = Reek::CLI::Application::STATUS_SUCCESS
27
+ expect(last_command_started).to have_exit_status(success)
27
28
  end
28
29
 
29
30
  Then /^the exit status indicates an error$/ do
30
- assert_exit_status Reek::CLI::Application::STATUS_ERROR
31
+ error = Reek::CLI::Application::STATUS_ERROR
32
+ expect(last_command_started).to have_exit_status(error)
31
33
  end
32
34
 
33
35
  Then /^the exit status indicates smells$/ do
34
- assert_exit_status Reek::CLI::Application::STATUS_SMELLS
36
+ smells = Reek::CLI::Application::STATUS_SMELLS
37
+ expect(last_command_started).to have_exit_status(smells)
35
38
  end
36
39
 
37
40
  Then /^it reports:$/ do |report|
38
- assert_exact_output "#{report}\n", all_stdout
41
+ expect(last_command_started).to have_output_on_stdout(report.gsub('\n', "\n"))
39
42
  end
40
43
 
41
44
  Then /^it reports this yaml:$/ do |expected_yaml|
42
45
  expected_warnings = YAML.load(expected_yaml.chomp)
43
- actual_warnings = YAML.load(all_stdout)
46
+ actual_warnings = YAML.load(last_command_started.stdout)
44
47
  expect(actual_warnings).to eq expected_warnings
45
48
  end
46
49
 
47
50
  Then /^it reports this JSON:$/ do |expected_json|
48
51
  expected_warnings = JSON.parse(expected_json.chomp)
49
- actual_warnings = JSON.parse(all_stdout)
52
+ actual_warnings = JSON.parse(last_command_started.stdout)
50
53
  expect(actual_warnings).to eq expected_warnings
51
54
  end
52
55
 
53
56
  Then /^stderr reports:$/ do |report|
54
- assert_exact_output report, all_stderr
57
+ expect(last_command_started).to have_output_on_stderr(report.chomp)
55
58
  end
56
59
 
57
60
  Then /^it reports no errors$/ do
58
- assert_exact_output '', all_stderr
61
+ expect(last_command_started).to have_output_on_stderr('')
59
62
  end
60
63
 
61
64
  Then /^it reports an error$/ do
62
- expect(all_stderr).to_not be_empty
65
+ expect(last_command_started.stderr).to_not be_empty
63
66
  end
64
67
 
65
68
  Then /^it reports the error ['"](.*)['"]$/ do |string|
66
- assert_partial_output string, all_stderr
69
+ expect(last_command_started).to have_output_on_stderr(/#{Regexp.escape(string)}/)
67
70
  end
68
71
 
69
72
  Then /^it reports a parsing error$/ do
70
- assert_partial_output 'Parser::SyntaxError', all_stderr
73
+ expect(last_command_started).to have_output_on_stderr(/Parser::SyntaxError/)
71
74
  end
72
75
 
73
76
  Then /^it should indicate the line numbers of those smells$/ do
74
- assert_matching_output /\[.*\]:/, all_stdout
77
+ expect(last_command_started).to have_output(/\[.*\]:/)
75
78
  end
76
79
 
77
80
  Then /^it reports the current version$/ do
78
- assert_exact_output "reek #{Reek::Version::STRING}\n", all_stdout
81
+ expect(last_command_started).to have_output("reek #{Reek::Version::STRING}")
79
82
  end
@@ -180,6 +180,14 @@ module Reek
180
180
  args.map { |arg| arg[1] }
181
181
  end
182
182
 
183
+ def module_creation_call?
184
+ object_creation_call? && module_creation_receiver?
185
+ end
186
+
187
+ def module_creation_receiver?
188
+ receiver && [:Class, :Struct].include?(receiver.simple_name)
189
+ end
190
+
183
191
  def object_creation_call?
184
192
  method_name == :new
185
193
  end
@@ -196,7 +204,7 @@ module Reek
196
204
  # Handles the case where we create an attribute writer via:
197
205
  # attr :foo, true
198
206
  def attr_with_writable_flag?
199
- method_name == :attr && args.last.type == :true
207
+ method_name == :attr && args.any? && args.last.type == :true
200
208
  end
201
209
 
202
210
  VISIBILITY_MODIFIERS = [:private, :public, :protected, :module_function]
@@ -231,8 +239,9 @@ module Reek
231
239
  # Utility methods for :lvar nodes.
232
240
  module LvarNode
233
241
  include VariableBase
234
- # TODO: Replace with name().
235
- def var_name() self[1] end
242
+
243
+ alias_method :simple_name, :name
244
+ alias_method :var_name, :name
236
245
  end
237
246
 
238
247
  LvasgnNode = LvarNode
@@ -353,6 +362,10 @@ module Reek
353
362
  def parameter_names
354
363
  parameters[1..-1].to_a
355
364
  end
365
+
366
+ def simple_name
367
+ :block
368
+ end
356
369
  end
357
370
 
358
371
  # Utility methods for :lit nodes.
@@ -419,8 +432,6 @@ module Reek
419
432
  module CasgnNode
420
433
  include ModuleNodeBase
421
434
 
422
- MODULE_DEFINERS = [:Class, :Struct]
423
-
424
435
  def defines_module?
425
436
  return false unless value
426
437
  call = case value.type
@@ -429,9 +440,7 @@ module Reek
429
440
  when :send
430
441
  value
431
442
  end
432
- call &&
433
- call.object_creation_call? &&
434
- MODULE_DEFINERS.include?(call.receiver.simple_name)
443
+ call && call.module_creation_call?
435
444
  end
436
445
 
437
446
  def name
@@ -1,5 +1,6 @@
1
1
  require_relative 'options'
2
2
  require_relative 'reek_command'
3
+ require_relative 'option_interpreter'
3
4
  require_relative '../configuration/app_configuration'
4
5
 
5
6
  module Reek
@@ -15,17 +16,14 @@ module Reek
15
16
  STATUS_SMELLS = 2
16
17
  attr_reader :configuration
17
18
 
19
+ private_attr_accessor :status
20
+ private_attr_reader :command, :options
21
+
18
22
  def initialize(argv)
19
23
  @status = STATUS_SUCCESS
20
- options_parser = Options.new(argv)
21
- begin
22
- options = options_parser.parse
23
- @command = ReekCommand.new(OptionInterpreter.new(options))
24
- @configuration = Configuration::AppConfiguration.from_path(options.config_file)
25
- rescue OptionParser::InvalidOption, Reek::Configuration::ConfigFileException => error
26
- $stderr.puts "Error: #{error}"
27
- @status = STATUS_ERROR
28
- end
24
+ @options = configure_options(argv)
25
+ @configuration = configure_app_configuration(options.config_file)
26
+ @command = ReekCommand.new(OptionInterpreter.new(options))
29
27
  end
30
28
 
31
29
  def execute
@@ -48,12 +46,23 @@ module Reek
48
46
 
49
47
  private
50
48
 
51
- private_attr_accessor :status
52
- private_attr_reader :command
53
-
54
49
  def error_occured?
55
50
  status == STATUS_ERROR
56
51
  end
52
+
53
+ def configure_options(argv)
54
+ Options.new(argv).parse
55
+ rescue OptionParser::InvalidOption => error
56
+ $stderr.puts "Error: #{error}"
57
+ exit STATUS_ERROR
58
+ end
59
+
60
+ def configure_app_configuration(config_file)
61
+ Configuration::AppConfiguration.from_path(config_file)
62
+ rescue Reek::Configuration::ConfigFileException => error
63
+ $stderr.puts "Error: #{error}"
64
+ exit STATUS_ERROR
65
+ end
57
66
  end
58
67
  end
59
68
  end
@@ -9,10 +9,9 @@ module Reek
9
9
  #
10
10
  class OptionInterpreter
11
11
  include Input
12
-
13
12
  extend Forwardable
14
-
15
13
  def_delegators :options, :smells_to_detect
14
+ private_attr_reader :argv, :options
16
15
 
17
16
  def initialize(options)
18
17
  @options = options
@@ -51,10 +50,6 @@ module Reek
51
50
  def sort_by_issue_count
52
51
  options.sorting == :smelliness
53
52
  end
54
-
55
- private
56
-
57
- private_attr_reader :argv, :options
58
53
  end
59
54
  end
60
55
  end
@@ -1,7 +1,5 @@
1
1
  require 'optparse'
2
- require 'ostruct'
3
2
  require 'rainbow'
4
- require_relative 'option_interpreter'
5
3
  require_relative '../version'
6
4
 
7
5
  module Reek
@@ -10,28 +8,40 @@ module Reek
10
8
  # Parses the command line
11
9
  #
12
10
  # See {file:docs/Command-Line-Options.md} for details.
11
+ #
12
+ # :reek:TooManyInstanceVariables: { max_instance_variables: 6 }
13
+ # :reek:Attribute: { enabled: false }
13
14
  class Options
15
+ attr_accessor :argv,
16
+ :colored,
17
+ :config_file,
18
+ :location_format,
19
+ :parser,
20
+ :report_format,
21
+ :show_empty,
22
+ :show_links,
23
+ :smells_to_detect,
24
+ :sorting
25
+
14
26
  def initialize(argv = [])
15
- @argv = argv
16
- @parser = OptionParser.new
17
- @options = OpenStruct.new(report_format: :text,
18
- location_format: :numbers,
19
- colored: color_support?,
20
- smells_to_detect: [])
27
+ @argv = argv
28
+ @parser = OptionParser.new
29
+ @report_format = :text
30
+ @location_format = :numbers
31
+ @smells_to_detect = []
32
+ @colored = color_support?
33
+
21
34
  set_up_parser
22
35
  end
23
36
 
24
37
  def parse
25
38
  parser.parse!(argv)
26
- options.argv = argv
27
- Rainbow.enabled = options.colored
28
- options
39
+ Rainbow.enabled = colored
40
+ self
29
41
  end
30
42
 
31
43
  private
32
44
 
33
- private_attr_reader :argv, :options, :parser
34
-
35
45
  # :reek:UtilityFunction
36
46
  def color_support?
37
47
  $stdout.tty?
@@ -68,7 +78,7 @@ module Reek
68
78
  'Report smells in the given format:',
69
79
  ' html', ' text (default)', ' yaml', ' json', ' xml'
70
80
  ) do |opt|
71
- options.report_format = opt
81
+ self.report_format = opt
72
82
  end
73
83
  end
74
84
 
@@ -77,10 +87,10 @@ module Reek
77
87
  parser.separator 'Configuration:'
78
88
  parser.on('-c', '--config FILE', 'Read configuration options from FILE') do |file|
79
89
  raise ArgumentError, "Config file #{file} doesn't exist" unless File.exist?(file)
80
- options.config_file = Pathname.new(file)
90
+ self.config_file = Pathname.new(file)
81
91
  end
82
92
  parser.on('--smell SMELL', 'Detect smell SMELL (default: all enabled smells)') do |smell|
83
- options.smells_to_detect << smell
93
+ smells_to_detect << smell
84
94
  end
85
95
  end
86
96
 
@@ -94,29 +104,29 @@ module Reek
94
104
 
95
105
  def set_up_color_option
96
106
  parser.on('--[no-]color', 'Use colors for the output (default: true)') do |opt|
97
- options.colored = opt
107
+ self.colored = opt
98
108
  end
99
109
  end
100
110
 
101
111
  def set_up_verbosity_options
102
112
  parser.on('-V', '--[no-]empty-headings',
103
113
  'Show headings for smell-free source files (default: false)') do |show_empty|
104
- options.show_empty = show_empty
114
+ self.show_empty = show_empty
105
115
  end
106
116
  parser.on('-U', '--[no-]wiki-links',
107
117
  'Show link to related wiki page for each smell (default: false)') do |show_links|
108
- options.show_links = show_links
118
+ self.show_links = show_links
109
119
  end
110
120
  end
111
121
 
112
122
  def set_up_location_formatting_options
113
123
  parser.on('-n', '--[no-]line-numbers',
114
124
  'Show line numbers in the output (default: true)') do |show_numbers|
115
- options.location_format = show_numbers ? :numbers : :plain
125
+ self.location_format = show_numbers ? :numbers : :plain
116
126
  end
117
127
  parser.on('-s', '--single-line',
118
128
  'Show location in editor-compatible single-line-per-smell format') do
119
- options.location_format = :single_line
129
+ self.location_format = :single_line
120
130
  end
121
131
  end
122
132
 
@@ -125,7 +135,7 @@ module Reek
125
135
  'Sort reported files by the given criterium:',
126
136
  ' smelliness ("smelliest" files first)',
127
137
  ' none (default - output in processing order)') do |sorting|
128
- options.sorting = sorting
138
+ self.sorting = sorting
129
139
  end
130
140
  end
131
141
 
@@ -4,7 +4,9 @@ module Reek
4
4
  # Formats the location of a warning as an empty string.
5
5
  #
6
6
  module BlankLocationFormatter
7
- def self.format(_warning)
7
+ module_function
8
+
9
+ def format(_warning)
8
10
  ''
9
11
  end
10
12
  end
@@ -13,8 +15,10 @@ module Reek
13
15
  # Formats the location of a warning as an array of line numbers.
14
16
  #
15
17
  module DefaultLocationFormatter
16
- def self.format(warning)
17
- "#{warning.lines.inspect}:"
18
+ module_function
19
+
20
+ def format(warning)
21
+ "#{warning.lines.sort.inspect}:"
18
22
  end
19
23
  end
20
24
 
@@ -24,8 +28,10 @@ module Reek
24
28
  # one line number, so the first number is displayed.
25
29
  #
26
30
  module SingleLineLocationFormatter
27
- def self.format(warning)
28
- "#{warning.source}:#{warning.lines.first}: "
31
+ module_function
32
+
33
+ def format(warning)
34
+ "#{warning.source}:#{warning.lines.sort.first}: "
29
35
  end
30
36
  end
31
37
  end
@@ -49,8 +49,16 @@ module Reek
49
49
  (self <=> other) == 0
50
50
  end
51
51
 
52
- def matches?(klass, other_parameters = {})
53
- smell_classes.include?(klass.to_s) && common_parameters_equal?(other_parameters)
52
+ def matches_smell_type?(klass)
53
+ smell_classes.include?(klass.to_s)
54
+ end
55
+
56
+ def matches_smell_details?(other_smell_details = {})
57
+ common_parameters_equal?(other_smell_details)
58
+ end
59
+
60
+ def matches?(klass, other_smell_details = {})
61
+ matches_smell_type?(klass) && matches_smell_details?(other_smell_details)
54
62
  end
55
63
 
56
64
  def report_on(listener)
@@ -18,16 +18,10 @@ module Reek
18
18
  #
19
19
  # See {file:docs/Uncommunicative-Method-Name.md} for details.
20
20
  class UncommunicativeMethodName < SmellDetector
21
- # The name of the config field that lists the regexps of
22
- # smelly names to be reported.
23
21
  REJECT_KEY = 'reject'
24
- DEFAULT_REJECT_SET = [/^[a-z]$/, /[0-9]$/, /[A-Z]/]
25
-
26
- # The name of the config field that lists the specific names that are
27
- # to be treated as exceptions; these names will not be reported as
28
- # uncommunicative.
29
22
  ACCEPT_KEY = 'accept'
30
- DEFAULT_ACCEPT_SET = []
23
+ DEFAULT_REJECT_PATTERNS = [/^[a-z]$/, /[0-9]$/, /[A-Z]/]
24
+ DEFAULT_ACCEPT_NAMES = []
31
25
 
32
26
  def self.smell_category
33
27
  'UncommunicativeName'
@@ -35,8 +29,8 @@ module Reek
35
29
 
36
30
  def self.default_config
37
31
  super.merge(
38
- REJECT_KEY => DEFAULT_REJECT_SET,
39
- ACCEPT_KEY => DEFAULT_ACCEPT_SET
32
+ REJECT_KEY => DEFAULT_REJECT_PATTERNS,
33
+ ACCEPT_KEY => DEFAULT_ACCEPT_NAMES
40
34
  )
41
35
  end
42
36
 
@@ -45,21 +39,31 @@ module Reek
45
39
  #
46
40
  # @return [Array<SmellWarning>]
47
41
  #
48
- # :reek:TooManyStatements: { max_statements: 9 }
49
- def examine_context(ctx)
50
- reject_names = value(REJECT_KEY, ctx, DEFAULT_REJECT_SET)
51
- accept_names = value(ACCEPT_KEY, ctx, DEFAULT_ACCEPT_SET)
52
- name = ctx.name.to_s
53
- return [] if accept_names.include?(ctx.full_name)
54
- var = name.gsub(/^[@\*\&]*/, '')
55
- return [] if accept_names.include?(var)
56
- return [] unless reject_names.find { |patt| patt =~ var }
42
+ def examine_context(context)
43
+ name = context.name.to_s
44
+ return [] if acceptable_name?(name: name, context: context)
45
+
57
46
  [smell_warning(
58
- context: ctx,
59
- lines: [ctx.exp.line],
47
+ context: context,
48
+ lines: [context.exp.line],
60
49
  message: "has the name '#{name}'",
61
50
  parameters: { name: name })]
62
51
  end
52
+
53
+ private
54
+
55
+ def acceptable_name?(name: raise, context: raise)
56
+ accept_names(context).any? { |accept_name| name == accept_name } ||
57
+ reject_patterns(context).none? { |pattern| name.match pattern }
58
+ end
59
+
60
+ def reject_patterns(context)
61
+ value(REJECT_KEY, context, DEFAULT_REJECT_PATTERNS)
62
+ end
63
+
64
+ def accept_names(context)
65
+ value(ACCEPT_KEY, context, DEFAULT_ACCEPT_NAMES)
66
+ end
63
67
  end
64
68
  end
65
69
  end