reek 5.6.0 → 6.0.3

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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/ruby.yml +52 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +3 -1
  6. data/.rubocop_todo.yml +27 -20
  7. data/.simplecov +1 -0
  8. data/CHANGELOG.md +24 -0
  9. data/Dockerfile +1 -0
  10. data/Gemfile +14 -17
  11. data/README.md +11 -11
  12. data/bin/code_climate_reek +12 -2
  13. data/docs/Attribute.md +1 -1
  14. data/docs/Boolean-Parameter.md +2 -2
  15. data/docs/Control-Couple.md +1 -1
  16. data/docs/Nil-Check.md +4 -1
  17. data/docs/templates/default/docstring/setup.rb +1 -3
  18. data/features/command_line_interface/options.feature +2 -3
  19. data/features/configuration_files/schema_validation.feature +1 -1
  20. data/features/reports/codeclimate.feature +2 -2
  21. data/features/reports/json.feature +3 -3
  22. data/features/reports/reports.feature +4 -4
  23. data/features/reports/yaml.feature +3 -3
  24. data/features/step_definitions/reek_steps.rb +5 -1
  25. data/features/step_definitions/sample_file_steps.rb +2 -2
  26. data/features/support/env.rb +0 -1
  27. data/lib/reek/ast/node.rb +1 -1
  28. data/lib/reek/ast/sexp_extensions/arguments.rb +11 -0
  29. data/lib/reek/cli/options.rb +3 -3
  30. data/lib/reek/code_comment.rb +36 -29
  31. data/lib/reek/configuration/app_configuration.rb +4 -3
  32. data/lib/reek/configuration/configuration_converter.rb +2 -2
  33. data/lib/reek/configuration/directory_directives.rb +9 -3
  34. data/lib/reek/configuration/excluded_paths.rb +2 -1
  35. data/lib/reek/context/code_context.rb +1 -1
  36. data/lib/reek/context/module_context.rb +3 -1
  37. data/lib/reek/context/refinement_context.rb +16 -0
  38. data/lib/reek/context_builder.rb +16 -2
  39. data/lib/reek/errors/legacy_comment_separator_error.rb +36 -0
  40. data/lib/reek/report/code_climate/code_climate_configuration.yml +1 -1
  41. data/lib/reek/report/code_climate/code_climate_report.rb +2 -1
  42. data/lib/reek/report/simple_warning_formatter.rb +0 -7
  43. data/lib/reek/report.rb +5 -7
  44. data/lib/reek/smell_detectors/base_detector.rb +1 -9
  45. data/lib/reek/smell_detectors/boolean_parameter.rb +3 -1
  46. data/lib/reek/smell_detectors/data_clump.rb +23 -56
  47. data/lib/reek/smell_detectors/nil_check.rb +1 -12
  48. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +1 -1
  49. data/lib/reek/smell_warning.rb +1 -2
  50. data/lib/reek/source/source_locator.rb +13 -10
  51. data/lib/reek/spec/smell_matcher.rb +2 -1
  52. data/lib/reek/version.rb +1 -1
  53. data/lib/reek.rb +1 -0
  54. data/reek.gemspec +13 -6
  55. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +2 -4
  56. data/spec/quality/documentation_spec.rb +2 -1
  57. data/spec/reek/ast/sexp_extensions_spec.rb +15 -33
  58. data/spec/reek/code_comment_spec.rb +41 -42
  59. data/spec/reek/configuration/directory_directives_spec.rb +6 -0
  60. data/spec/reek/configuration/excluded_paths_spec.rb +12 -3
  61. data/spec/reek/context_builder_spec.rb +110 -113
  62. data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +1 -3
  63. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +26 -26
  64. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  65. data/spec/reek/report/location_formatter_spec.rb +3 -3
  66. data/spec/reek/smell_detectors/base_detector_spec.rb +3 -13
  67. data/spec/reek/smell_detectors/data_clump_spec.rb +14 -0
  68. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +8 -2
  69. data/spec/reek/smell_detectors/nil_check_spec.rb +3 -3
  70. data/spec/reek/smell_detectors/utility_function_spec.rb +16 -0
  71. data/spec/reek/smell_warning_spec.rb +12 -12
  72. data/spec/reek/source/source_code_spec.rb +13 -0
  73. data/spec/reek/spec/should_reek_of_spec.rb +0 -1
  74. data/spec/reek/spec/should_reek_only_of_spec.rb +6 -6
  75. data/spec/reek/spec/smell_matcher_spec.rb +1 -1
  76. data/spec/spec_helper.rb +19 -5
  77. data/tasks/configuration.rake +1 -2
  78. metadata +24 -42
  79. data/.travis.yml +0 -35
  80. data/spec/factories/factories.rb +0 -37
@@ -33,23 +33,26 @@ module Reek
33
33
 
34
34
  attr_reader :configuration, :paths, :options
35
35
 
36
- # @quality :reek:TooManyStatements { max_statements: 7 }
37
- # @quality :reek:NestedIterators { max_allowed_nesting: 2 }
38
36
  def source_paths
39
37
  paths.each_with_object([]) do |given_path, relevant_paths|
40
- unless given_path.exist?
38
+ if given_path.exist?
39
+ relevant_paths.concat source_files_from_path(given_path)
40
+ else
41
41
  print_no_such_file_error(given_path)
42
- next
43
42
  end
43
+ end
44
+ end
44
45
 
45
- given_path.find do |path|
46
- if path.directory?
47
- ignore_path?(path) ? Find.prune : next
48
- elsif ruby_file?(path)
49
- relevant_paths << path unless ignore_file?(path)
50
- end
46
+ def source_files_from_path(given_path)
47
+ relevant_paths = []
48
+ given_path.find do |path|
49
+ if path.directory?
50
+ Find.prune if ignore_path?(path)
51
+ elsif ruby_file?(path)
52
+ relevant_paths << path unless ignore_file?(path)
51
53
  end
52
54
  end
55
+ relevant_paths
53
56
  end
54
57
 
55
58
  def ignore_file?(path)
@@ -43,8 +43,9 @@ module Reek
43
43
  raise ArgumentError, "The attribute '#{extra_keys.first}' is not available for comparison"
44
44
  end
45
45
 
46
+ # :reek:FeatureEnvy
46
47
  def common_parameters_equal?(other_parameters)
47
- smell_warning.parameters.slice(*other_parameters.keys) == other_parameters
48
+ smell_warning.parameters.values_at(*other_parameters.keys) == other_parameters.values
48
49
  end
49
50
 
50
51
  def common_attributes_equal?(attributes)
data/lib/reek/version.rb CHANGED
@@ -8,6 +8,6 @@ module Reek
8
8
  # @public
9
9
  module Version
10
10
  # @public
11
- STRING = '5.6.0'
11
+ STRING = '6.0.3'
12
12
  end
13
13
  end
data/lib/reek.rb CHANGED
@@ -8,6 +8,7 @@ require_relative 'reek/examiner'
8
8
  require_relative 'reek/report'
9
9
 
10
10
  module Reek
11
+ DEFAULT_SMELL_CONFIGURATION = File.join(__dir__, '../docs/defaults.reek.yml').freeze
11
12
  DEFAULT_CONFIGURATION_FILE_NAME = '.reek.yml'
12
13
  DETECTORS_KEY = 'detectors'
13
14
  EXCLUDE_PATHS_KEY = 'exclude_paths'
data/reek.gemspec CHANGED
@@ -16,12 +16,19 @@ Gem::Specification.new do |s|
16
16
  s.executables = s.files.grep(%r{^bin/}).map { |path| File.basename(path) }
17
17
  s.homepage = 'https://github.com/troessner/reek'
18
18
  s.rdoc_options = %w(--main README.md -x assets/|bin/|config/|features/|spec/|tasks/)
19
- s.required_ruby_version = '>= 2.3.0'
19
+ s.required_ruby_version = '>= 2.4.0'
20
20
  s.summary = 'Code smell detector for Ruby'
21
21
 
22
- s.add_runtime_dependency 'codeclimate-engine-rb', '~> 0.4.0'
23
- s.add_runtime_dependency 'kwalify', '~> 0.7.0'
24
- s.add_runtime_dependency 'parser', '< 2.8', '>= 2.5.0.0', '!= 2.5.1.1'
25
- s.add_runtime_dependency 'psych', '~> 3.1.0'
26
- s.add_runtime_dependency 'rainbow', '>= 2.0', '< 4.0'
22
+ s.metadata = {
23
+ 'homepage_uri' => 'https://github.com/troessner/reek',
24
+ 'source_code_uri' => 'https://github.com/troessner/reek',
25
+ 'bug_tracker_uri' => 'https://github.com/troessner/reek/issues',
26
+ 'changelog_uri' => 'https://github.com/troessner/reek/CHANGELOG.md',
27
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/reek'
28
+ }
29
+
30
+ s.add_runtime_dependency 'kwalify', '~> 0.7.0'
31
+ s.add_runtime_dependency 'parser', '~> 3.0.0'
32
+ s.add_runtime_dependency 'psych', '~> 3.1'
33
+ s.add_runtime_dependency 'rainbow', '>= 2.0', '< 4.0'
27
34
  end
@@ -6,10 +6,8 @@ RSpec.describe 'Runtime speed' do
6
6
 
7
7
  it 'runs on our smelly sources in less than 5 seconds' do
8
8
  expect do
9
- source_directory.each_entry do |entry|
10
- next if %w(. ..).include?(entry.to_s)
11
-
12
- examiner = Reek::Examiner.new entry.to_path
9
+ Dir[source_directory.join('**/*.rb')].each do |entry|
10
+ examiner = Reek::Examiner.new Pathname.new(entry)
13
11
  examiner.smells.size
14
12
  end
15
13
  end.to perform_under(5).sec
@@ -4,6 +4,7 @@ require 'kramdown'
4
4
  RSpec.describe 'Documentation' do
5
5
  root = File.expand_path('../..', __dir__)
6
6
  files = Dir.glob(File.join(root, '*.md')) + Dir.glob(File.join(root, 'docs', '*.md'))
7
+ code_types = [:codeblock, :codespan]
7
8
 
8
9
  files.each do |file|
9
10
  describe "from #{file}" do
@@ -13,7 +14,7 @@ RSpec.describe 'Documentation' do
13
14
 
14
15
  blocks.each do |block|
15
16
  # Only consider code blocks with language 'ruby'.
16
- next unless [:codeblock, :codespan].include?(block.type)
17
+ next unless code_types.include?(block.type)
17
18
  next unless block.attr['class'] == 'language-ruby'
18
19
 
19
20
  it "has a valid sample at #{block.options[:location] + 1}" do
@@ -443,73 +443,55 @@ end
443
443
 
444
444
  RSpec.describe Reek::AST::SexpExtensions::CasgnNode do
445
445
  describe '#defines_module?' do
446
- context 'with single assignment' do
447
- it 'does not define a module' do
448
- exp = sexp(:casgn, nil, :Foo)
449
- expect(exp).not_to be_defines_module
450
- end
446
+ it 'is false for single assignment' do
447
+ exp = sexp(:casgn, nil, :Foo)
448
+ expect(exp).not_to be_defines_module
451
449
  end
452
450
 
453
- context 'with implicit receiver to new' do
454
- it 'does not define a module' do
455
- exp = sexp(:casgn, nil, :Foo, sexp(:send, nil, :new))
456
- expect(exp).not_to be_defines_module
457
- end
451
+ it 'is false for implicit receiver to new' do
452
+ exp = sexp(:casgn, nil, :Foo, sexp(:send, nil, :new))
453
+ expect(exp).not_to be_defines_module
458
454
  end
459
455
 
460
- context 'with implicit receiver to new' do
461
- it 'does not define a module' do
462
- exp = Reek::Source::SourceCode.from('Foo = Class.new(Bar)').syntax_tree
463
-
464
- expect(exp).to be_defines_module
465
- end
456
+ it 'is true for explicit receiver to new' do
457
+ exp = Reek::Source::SourceCode.from('Foo = Class.new(Bar)').syntax_tree
458
+ expect(exp).to be_defines_module
466
459
  end
467
460
 
468
- context 'when assigning a lambda to a constant' do
469
- it 'does not define a module' do
470
- exp = Reek::Source::SourceCode.from('C = ->{}').syntax_tree
471
-
472
- expect(exp).not_to be_defines_module
473
- end
461
+ it 'is false for assigning a lambda to a constant' do
462
+ exp = Reek::Source::SourceCode.from('C = ->{}').syntax_tree
463
+ expect(exp).not_to be_defines_module
474
464
  end
475
465
 
476
- context 'when assigning a string to a constant' do
477
- it 'does not define a module' do
478
- exp = Reek::Source::SourceCode.from('C = "hello"').syntax_tree
479
-
480
- expect(exp).not_to be_defines_module
481
- end
466
+ it 'is false for assigning a string to a constant' do
467
+ exp = Reek::Source::SourceCode.from('C = "hello"').syntax_tree
468
+ expect(exp).not_to be_defines_module
482
469
  end
483
470
  end
484
471
 
485
472
  describe '#superclass' do
486
473
  it 'returns the superclass from the class definition' do
487
474
  exp = Reek::Source::SourceCode.from('Foo = Class.new(Bar)').syntax_tree
488
-
489
475
  expect(exp.superclass).to eq sexp(:const, nil, :Bar)
490
476
  end
491
477
 
492
478
  it 'returns nil in case of no class definition' do
493
479
  exp = Reek::Source::SourceCode.from('Foo = 23').syntax_tree
494
-
495
480
  expect(exp.superclass).to be_nil
496
481
  end
497
482
 
498
483
  it 'returns nil in case of no superclass' do
499
484
  exp = Reek::Source::SourceCode.from('Foo = Class.new').syntax_tree
500
-
501
485
  expect(exp.superclass).to be_nil
502
486
  end
503
487
 
504
488
  it 'returns nothing for a class definition using Struct.new' do
505
489
  exp = Reek::Source::SourceCode.from('Foo = Struct.new("Bar")').syntax_tree
506
-
507
490
  expect(exp.superclass).to be_nil
508
491
  end
509
492
 
510
493
  it 'returns nothing for a constant assigned with a bare method call' do
511
494
  exp = Reek::Source::SourceCode.from('Foo = foo("Bar")').syntax_tree
512
-
513
495
  expect(exp.superclass).to be_nil
514
496
  end
515
497
  end
@@ -3,7 +3,7 @@ require_lib 'reek/code_comment'
3
3
 
4
4
  RSpec.describe Reek::CodeComment do
5
5
  context 'with an empty comment' do
6
- let(:comment) { build(:code_comment, comment: '') }
6
+ let(:comment) { build_code_comment(comment: '') }
7
7
 
8
8
  it 'is not descriptive' do
9
9
  expect(comment).not_to be_descriptive
@@ -16,77 +16,63 @@ RSpec.describe Reek::CodeComment do
16
16
 
17
17
  describe '#descriptive' do
18
18
  it 'rejects an empty comment' do
19
- comment = build(:code_comment, comment: '#')
19
+ comment = build_code_comment(comment: '#')
20
20
  expect(comment).not_to be_descriptive
21
21
  end
22
22
 
23
23
  it 'rejects a 1-word comment' do
24
- comment = build(:code_comment, comment: "# alpha\n# ")
24
+ comment = build_code_comment(comment: "# alpha\n# ")
25
25
  expect(comment).not_to be_descriptive
26
26
  end
27
27
 
28
28
  it 'accepts a 2-word comment' do
29
- comment = build(:code_comment, comment: '# alpha bravo ')
29
+ comment = build_code_comment(comment: '# alpha bravo ')
30
30
  expect(comment).to be_descriptive
31
31
  end
32
32
 
33
33
  it 'accepts a multi-word comment' do
34
- comment = build(:code_comment, comment: "# alpha bravo \n# charlie \n # delta ")
34
+ comment = build_code_comment(comment: "# alpha bravo \n# charlie \n # delta ")
35
35
  expect(comment).to be_descriptive
36
36
  end
37
37
  end
38
38
 
39
39
  describe 'good comment config' do
40
40
  it 'parses hashed options' do
41
- comment = '# :reek:DuplicateMethodCall { enabled: false }'
42
- config = build(:code_comment,
43
- comment: comment).config
41
+ comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
42
+ config = build_code_comment(comment: comment).config
44
43
 
45
44
  expect(config).to include('DuplicateMethodCall')
46
- expect(config['DuplicateMethodCall']).to include('enabled')
47
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
48
- end
49
-
50
- it "supports hashed options with the legacy separator ':' after the smell detector" do
51
- comment = '# :reek:DuplicateMethodCall: { enabled: false }'
52
- config = build(:code_comment,
53
- comment: comment).config
54
-
55
- expect(config).to include('DuplicateMethodCall')
56
- expect(config['DuplicateMethodCall']).to include('enabled')
57
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
45
+ expect(config['DuplicateMethodCall']).to have_key 'max_calls'
46
+ expect(config['DuplicateMethodCall']['max_calls']).to eq 3
58
47
  end
59
48
 
60
49
  it 'parses multiple hashed options' do
61
50
  comment = <<-RUBY
62
- # :reek:DuplicateMethodCall { enabled: false }
51
+ # :reek:DuplicateMethodCall { max_calls: 3 }
63
52
  # :reek:NestedIterators { enabled: true }
64
53
  RUBY
65
- config = build(:code_comment, comment: comment).config
54
+ config = build_code_comment(comment: comment).config
66
55
 
67
56
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
68
- expect(config['DuplicateMethodCall']).to include('enabled')
69
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
70
- expect(config['NestedIterators']).to include('enabled')
57
+ expect(config['DuplicateMethodCall']['max_calls']).to eq 3
71
58
  expect(config['NestedIterators']['enabled']).to be_truthy
72
59
  end
73
60
 
74
61
  it 'parses multiple hashed options on the same line' do
75
62
  comment = <<-RUBY
76
- #:reek:DuplicateMethodCall { enabled: false } and :reek:NestedIterators { enabled: true }
63
+ #:reek:DuplicateMethodCall { max_calls: 3 } and :reek:NestedIterators { enabled: true }
77
64
  RUBY
78
- config = build(:code_comment, comment: comment).config
65
+ config = build_code_comment(comment: comment).config
79
66
 
80
67
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
81
- expect(config['DuplicateMethodCall']).to include('enabled')
82
- expect(config['DuplicateMethodCall']['enabled']).to be_falsey
68
+ expect(config['DuplicateMethodCall']['max_calls']).to eq 3
83
69
  expect(config['NestedIterators']).to include('enabled')
84
70
  expect(config['NestedIterators']['enabled']).to be_truthy
85
71
  end
86
72
 
87
73
  it 'parses multiple unhashed options on the same line' do
88
74
  comment = '# :reek:DuplicateMethodCall and :reek:NestedIterators'
89
- config = build(:code_comment, comment: comment).config
75
+ config = build_code_comment(comment: comment).config
90
76
 
91
77
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
92
78
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -97,27 +83,33 @@ RSpec.describe Reek::CodeComment do
97
83
 
98
84
  it 'disables the smell if no options are specifed' do
99
85
  comment = '# :reek:DuplicateMethodCall'
100
- config = build(:code_comment, comment: comment).config
86
+ config = build_code_comment(comment: comment).config
101
87
 
102
88
  expect(config).to include('DuplicateMethodCall')
103
89
  expect(config['DuplicateMethodCall']).to include('enabled')
104
90
  expect(config['DuplicateMethodCall']['enabled']).to be_falsey
105
91
  end
106
92
 
93
+ it 'does not disable the smell if options are specifed' do
94
+ comment = '# :reek:DuplicateMethodCall { max_calls: 3 }'
95
+ config = build_code_comment(comment: comment).config
96
+
97
+ expect(config['DuplicateMethodCall']).not_to include('enabled')
98
+ end
99
+
107
100
  it 'ignores smells after a space' do
108
- config = build(:code_comment,
109
- comment: '# :reek: DuplicateMethodCall').config
101
+ config = build_code_comment(comment: '# :reek: DuplicateMethodCall').config
110
102
  expect(config).not_to include('DuplicateMethodCall')
111
103
  end
112
104
 
113
105
  it 'removes the configuration options from the comment' do
114
106
  original_comment = <<-RUBY
115
107
  # Actual
116
- # :reek:DuplicateMethodCall { enabled: false }
108
+ # :reek:DuplicateMethodCall { max_calls: 3 }
117
109
  # :reek:NestedIterators { enabled: true }
118
110
  # comment
119
111
  RUBY
120
- comment = build(:code_comment, comment: original_comment)
112
+ comment = build_code_comment(comment: original_comment)
121
113
 
122
114
  expect(comment.send(:sanitized_comment)).to eq('Actual comment')
123
115
  end
@@ -128,8 +120,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
128
120
  context 'when the comment contains an unknown detector name' do
129
121
  it 'raises BadDetectorInCommentError' do
130
122
  expect do
131
- build(:code_comment,
132
- comment: '# :reek:DoesNotExist')
123
+ build_code_comment(comment: '# :reek:DoesNotExist')
133
124
  end.to raise_error(Reek::Errors::BadDetectorInCommentError)
134
125
  end
135
126
  end
@@ -138,18 +129,26 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
138
129
  it 'raises GarbageDetectorConfigurationInCommentError' do
139
130
  expect do
140
131
  comment = '# :reek:UncommunicativeMethodName { thats: a: bad: config }'
141
- build(:code_comment, comment: comment)
132
+ build_code_comment(comment: comment)
142
133
  end.to raise_error(Reek::Errors::GarbageDetectorConfigurationInCommentError)
143
134
  end
144
135
  end
145
136
 
137
+ context 'when the legacy comment format was used' do
138
+ it 'raises LegacyCommentSeparatorError' do
139
+ comment = '# :reek:DuplicateMethodCall:'
140
+ expect { build_code_comment(comment: comment) }.
141
+ to raise_error Reek::Errors::LegacyCommentSeparatorError
142
+ end
143
+ end
144
+
146
145
  describe 'validating configuration keys' do
147
146
  context 'when basic options are mispelled' do
148
147
  it 'raises BadDetectorConfigurationKeyInCommentError' do
149
148
  expect do
150
149
  # exclude -> exlude and enabled -> nabled
151
150
  comment = '# :reek:UncommunicativeMethodName { exlude: alfa, nabled: true }'
152
- build(:code_comment, comment: comment)
151
+ build_code_comment(comment: comment)
153
152
  end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
154
153
  end
155
154
  end
@@ -158,7 +157,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
158
157
  it 'does not raise' do
159
158
  expect do
160
159
  comment = '# :reek:UncommunicativeMethodName { exclude: alfa, enabled: true }'
161
- build(:code_comment, comment: comment)
160
+ build_code_comment(comment: comment)
162
161
  end.not_to raise_error
163
162
  end
164
163
  end
@@ -168,7 +167,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
168
167
  expect do
169
168
  # max_copies -> mx_copies and min_clump_size -> mn_clump_size
170
169
  comment = '# :reek:DataClump { mx_copies: 4, mn_clump_size: 3 }'
171
- build(:code_comment, comment: comment)
170
+ build_code_comment(comment: comment)
172
171
  end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
173
172
  end
174
173
  end
@@ -177,7 +176,7 @@ RSpec.describe Reek::CodeComment::CodeCommentValidator do
177
176
  it 'does not raise' do
178
177
  expect do
179
178
  comment = '# :reek:DataClump { max_copies: 4, min_clump_size: 3 }'
180
- build(:code_comment, comment: comment)
179
+ build_code_comment(comment: comment)
181
180
  end.not_to raise_error
182
181
  end
183
182
  end
@@ -89,6 +89,12 @@ RSpec.describe Reek::Configuration::DirectoryDirectives do
89
89
  expect(hit.to_s).to eq('bar/**/.spec/*')
90
90
  end
91
91
 
92
+ it 'returns the corresponding directory when source_base_dir is an absolute_path' do
93
+ source_base_dir = Pathname.new('foo/bar').expand_path
94
+ hit = directives.send :best_match_for, source_base_dir
95
+ expect(hit.to_s).to eq('foo/bar')
96
+ end
97
+
92
98
  it 'does not match an arbitrary directory when source_base_dir contains a character that could match the .' do
93
99
  source_base_dir = 'bar/something/aspec/direct'
94
100
  hit = directives.send :best_match_for, source_base_dir
@@ -5,12 +5,21 @@ require_lib 'reek/configuration/excluded_paths'
5
5
  RSpec.describe Reek::Configuration::ExcludedPaths do
6
6
  describe '#add' do
7
7
  let(:exclusions) { [].extend(described_class) }
8
- let(:paths) { ['smelly/sources'] }
9
- let(:expected_exclude_paths) { [Pathname('smelly/sources')] }
8
+ let(:paths) do
9
+ %w(samples/directory_does_not_exist/
10
+ samples/source_with_non_ruby_files/
11
+ samples/**/ignore_me*)
12
+ end
13
+
14
+ let(:expected_exclude_paths) do
15
+ [Pathname('samples/source_with_non_ruby_files/'),
16
+ Pathname('samples/source_with_exclude_paths/ignore_me'),
17
+ Pathname('samples/source_with_exclude_paths/nested/ignore_me_as_well')]
18
+ end
10
19
 
11
20
  it 'adds the given paths as Pathname' do
12
21
  exclusions.add(paths)
13
- expect(exclusions).to eq expected_exclude_paths
22
+ expect(exclusions).to match_array expected_exclude_paths
14
23
  end
15
24
  end
16
25
  end