reek 4.4.1 → 4.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +46 -0
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +5 -1
  5. data/docs/Duplicate-Method-Call.md +96 -0
  6. data/docs/How-To-Write-New-Detectors.md +16 -0
  7. data/docs/Large-Class.md +2 -1
  8. data/docs/Simulated-Polymorphism.md +1 -1
  9. data/features/configuration_via_source_comments/erroneous_source_comments.feature +39 -0
  10. data/lib/reek/ast/node.rb +4 -0
  11. data/lib/reek/code_comment.rb +11 -3
  12. data/lib/reek/context/code_context.rb +3 -1
  13. data/lib/reek/context/module_context.rb +1 -1
  14. data/lib/reek/errors.rb +32 -0
  15. data/lib/reek/examiner.rb +6 -1
  16. data/lib/reek/rake/task.rb +0 -2
  17. data/lib/reek/smells/boolean_parameter.rb +1 -1
  18. data/lib/reek/smells/class_variable.rb +2 -2
  19. data/lib/reek/smells/instance_variable_assumption.rb +1 -1
  20. data/lib/reek/smells/prima_donna_method.rb +18 -17
  21. data/lib/reek/smells/smell_detector.rb +19 -2
  22. data/lib/reek/smells/unused_private_method.rb +1 -1
  23. data/lib/reek/spec/should_reek_of.rb +2 -0
  24. data/lib/reek/version.rb +1 -1
  25. data/spec/factories/factories.rb +11 -0
  26. data/spec/quality/reek_source_spec.rb +1 -1
  27. data/spec/reek/ast/node_spec.rb +40 -0
  28. data/spec/reek/ast/object_refs_spec.rb +20 -59
  29. data/spec/reek/ast/sexp_extensions_spec.rb +16 -19
  30. data/spec/reek/cli/application_spec.rb +25 -25
  31. data/spec/reek/cli/command/report_command_spec.rb +1 -2
  32. data/spec/reek/cli/command/todo_list_command_spec.rb +1 -1
  33. data/spec/reek/cli/options_spec.rb +7 -5
  34. data/spec/reek/code_comment_spec.rb +74 -44
  35. data/spec/reek/configuration/default_directive_spec.rb +3 -3
  36. data/spec/reek/configuration/directory_directives_spec.rb +10 -10
  37. data/spec/reek/configuration/excluded_paths_spec.rb +2 -2
  38. data/spec/reek/context/code_context_spec.rb +22 -26
  39. data/spec/reek/context/ghost_context_spec.rb +1 -1
  40. data/spec/reek/context/method_context_spec.rb +13 -7
  41. data/spec/reek/context/module_context_spec.rb +4 -4
  42. data/spec/reek/context/root_context_spec.rb +1 -1
  43. data/spec/reek/context_builder_spec.rb +34 -38
  44. data/spec/reek/examiner_spec.rb +43 -22
  45. data/spec/reek/rake/task_spec.rb +3 -3
  46. data/spec/reek/report/code_climate_formatter_spec.rb +42 -40
  47. data/spec/reek/report/code_climate_report_spec.rb +1 -1
  48. data/spec/reek/report/html_report_spec.rb +1 -1
  49. data/spec/reek/report/json_report_spec.rb +1 -1
  50. data/spec/reek/report/location_formatter_spec.rb +18 -16
  51. data/spec/reek/report/text_report_spec.rb +12 -8
  52. data/spec/reek/report/xml_report_spec.rb +1 -1
  53. data/spec/reek/report/yaml_report_spec.rb +1 -1
  54. data/spec/reek/report_spec.rb +4 -4
  55. data/spec/reek/smells/attribute_spec.rb +7 -10
  56. data/spec/reek/smells/boolean_parameter_spec.rb +14 -20
  57. data/spec/reek/smells/class_variable_spec.rb +6 -5
  58. data/spec/reek/smells/control_parameter_spec.rb +3 -2
  59. data/spec/reek/smells/data_clump_spec.rb +3 -6
  60. data/spec/reek/smells/duplicate_method_call_spec.rb +10 -14
  61. data/spec/reek/smells/feature_envy_spec.rb +34 -25
  62. data/spec/reek/smells/instance_variable_assumption_spec.rb +6 -9
  63. data/spec/reek/smells/irresponsible_module_spec.rb +3 -6
  64. data/spec/reek/smells/long_parameter_list_spec.rb +5 -7
  65. data/spec/reek/smells/long_yield_list_spec.rb +3 -6
  66. data/spec/reek/smells/manual_dispatch_spec.rb +3 -6
  67. data/spec/reek/smells/nested_iterators_spec.rb +10 -8
  68. data/spec/reek/smells/nil_check_spec.rb +2 -1
  69. data/spec/reek/smells/prima_donna_method_spec.rb +5 -8
  70. data/spec/reek/smells/smell_configuration_spec.rb +3 -3
  71. data/spec/reek/smells/smell_detector_spec.rb +10 -0
  72. data/spec/reek/smells/smell_repository_spec.rb +6 -6
  73. data/spec/reek/smells/smell_warning_spec.rb +35 -39
  74. data/spec/reek/smells/subclassed_from_core_class_spec.rb +5 -5
  75. data/spec/reek/smells/too_many_constants_spec.rb +10 -10
  76. data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
  77. data/spec/reek/smells/too_many_methods_spec.rb +1 -1
  78. data/spec/reek/smells/too_many_statements_spec.rb +3 -6
  79. data/spec/reek/smells/uncommunicative_method_name_spec.rb +9 -6
  80. data/spec/reek/smells/uncommunicative_module_name_spec.rb +3 -3
  81. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +6 -9
  82. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +20 -24
  83. data/spec/reek/smells/unused_parameters_spec.rb +35 -24
  84. data/spec/reek/smells/unused_private_method_spec.rb +25 -33
  85. data/spec/reek/smells/utility_function_spec.rb +27 -14
  86. data/spec/reek/source/source_code_spec.rb +6 -6
  87. data/spec/reek/source/source_locator_spec.rb +34 -17
  88. data/spec/reek/spec/should_reek_of_spec.rb +17 -12
  89. data/spec/reek/spec/should_reek_only_of_spec.rb +5 -5
  90. data/spec/reek/spec/should_reek_spec.rb +3 -3
  91. data/spec/reek/tree_dresser_spec.rb +6 -4
  92. data/spec/spec_helper.rb +3 -0
  93. data/tasks/rubocop.rake +9 -3
  94. metadata +4 -2
@@ -17,31 +17,37 @@ RSpec.describe Reek::Smells::UtilityFunction do
17
17
  end
18
18
 
19
19
  it 'counts a local call in a param initializer' do
20
- expect('def alfa(bravo = charlie) bravo.to_s end').not_to reek_of(:UtilityFunction)
20
+ src = 'def alfa(bravo = charlie) bravo.to_s end'
21
+ expect(src).not_to reek_of(:UtilityFunction)
21
22
  end
22
23
 
23
24
  it 'counts usages of self' do
24
- expect('def alfa(bravo); alfa.bravo(self); end').not_to reek_of(:UtilityFunction)
25
+ src = 'def alfa(bravo); alfa.bravo(self); end'
26
+ expect(src).not_to reek_of(:UtilityFunction)
25
27
  end
26
28
 
27
29
  it 'counts self reference within a dstr' do
28
- expect('def alfa(bravo); "#{self} #{bravo}"; end').not_to reek_of(:UtilityFunction)
30
+ src = 'def alfa(bravo); "#{self} #{bravo}"; end'
31
+ expect(src).not_to reek_of(:UtilityFunction)
29
32
  end
30
33
 
31
34
  it 'counts calls to self within a dstr' do
32
- expect('def alfa(bravo); "#{self.gsub(/charlie/, /delta/)}"; end').
35
+ src = 'def alfa(bravo); "#{self.gsub(/charlie/, /delta/)}"; end'
36
+ expect(src).
33
37
  not_to reek_of(:UtilityFunction)
34
38
  end
35
39
 
36
40
  it 'does not report a method that calls super' do
37
- expect('def alfa(bravo) super; bravo.to_s; end').not_to reek_of(:UtilityFunction)
41
+ src = 'def alfa(bravo) super; bravo.to_s; end'
42
+ expect(src).not_to reek_of(:UtilityFunction)
38
43
  end
39
44
 
40
45
  it 'does not report a method that calls super with arguments' do
41
- expect('def alfa(bravo) super(bravo); bravo.to_s; end').not_to reek_of(:UtilityFunction)
46
+ src = 'def alfa(bravo) super(bravo); bravo.to_s; end'
47
+ expect(src).not_to reek_of(:UtilityFunction)
42
48
  end
43
49
 
44
- it 'should recognise a deep call' do
50
+ it 'recognises a deep call' do
45
51
  src = <<-EOS
46
52
  class Alfa
47
53
  def bravo(charlie)
@@ -58,31 +64,38 @@ RSpec.describe Reek::Smells::UtilityFunction do
58
64
  end
59
65
 
60
66
  it 'does not report empty method' do
61
- expect('def alfa(bravo); end').not_to reek_of(:UtilityFunction)
67
+ src = 'def alfa(bravo); end'
68
+ expect(src).not_to reek_of(:UtilityFunction)
62
69
  end
63
70
 
64
71
  it 'does not report literal' do
65
- expect('def alfa; 3; end').not_to reek_of(:UtilityFunction)
72
+ src = 'def alfa; 3; end'
73
+ expect(src).not_to reek_of(:UtilityFunction)
66
74
  end
67
75
 
68
76
  it 'does not report instance variable reference' do
69
- expect('def alfa; @bravo; end').not_to reek_of(:UtilityFunction)
77
+ src = 'def alfa; @bravo; end'
78
+ expect(src).not_to reek_of(:UtilityFunction)
70
79
  end
71
80
 
72
81
  it 'does not report vcall' do
73
- expect('def alfa; bravo; end').not_to reek_of(:UtilityFunction)
82
+ src = 'def alfa; bravo; end'
83
+ expect(src).not_to reek_of(:UtilityFunction)
74
84
  end
75
85
 
76
86
  it 'does not report references to self' do
77
- expect('def alfa; self; end').not_to reek_of(:UtilityFunction)
87
+ src = 'def alfa; self; end'
88
+ expect(src).not_to reek_of(:UtilityFunction)
78
89
  end
79
90
 
80
91
  it 'recognises an ivar reference within a block' do
81
- expect('def alfa(bravo) bravo.each { @charlie = 3} end').not_to reek_of(:UtilityFunction)
92
+ src = 'def alfa(bravo) bravo.each { @charlie = 3} end'
93
+ expect(src).not_to reek_of(:UtilityFunction)
82
94
  end
83
95
 
84
96
  it 'reports a call to a constant' do
85
- expect('def simple(arga) FIELDS[arga] end').to reek_of(:UtilityFunction, context: 'simple')
97
+ src = 'def simple(arga) FIELDS[arga] end'
98
+ expect(src).to reek_of(:UtilityFunction, context: 'simple')
86
99
  end
87
100
 
88
101
  context 'Singleton methods' do
@@ -6,20 +6,20 @@ RSpec.describe Reek::Source::SourceCode do
6
6
  describe '#syntax_tree' do
7
7
  it 'associates comments with the AST' do
8
8
  source = "# this is\n# a comment\ndef foo; end"
9
- source_code = Reek::Source::SourceCode.new(code: source, origin: '(string)')
9
+ source_code = described_class.new(code: source, origin: '(string)')
10
10
  result = source_code.syntax_tree
11
11
  expect(result.leading_comment).to eq "# this is\n# a comment"
12
12
  end
13
13
 
14
14
  it 'cleanly processes empty source' do
15
- source_code = Reek::Source::SourceCode.new(code: '', origin: '(string)')
15
+ source_code = described_class.new(code: '', origin: '(string)')
16
16
  result = source_code.syntax_tree
17
17
  expect(result).to be_nil
18
18
  end
19
19
 
20
20
  it 'cleanly processes empty source with comments' do
21
21
  source = "# this is\n# a comment\n"
22
- source_code = Reek::Source::SourceCode.new(code: source, origin: '(string)')
22
+ source_code = described_class.new(code: source, origin: '(string)')
23
23
  result = source_code.syntax_tree
24
24
  expect(result).to be_nil
25
25
  end
@@ -29,8 +29,8 @@ RSpec.describe Reek::Source::SourceCode do
29
29
  let(:catcher) { StringIO.new }
30
30
  let(:source_name) { 'Test source' }
31
31
  let(:error_message) { 'Error message' }
32
- let(:parser) { double('parser') }
33
- let(:src) { Reek::Source::SourceCode.new(code: '', origin: source_name, parser: parser) }
32
+ let(:parser) { class_double(Parser::Ruby23) }
33
+ let(:src) { described_class.new(code: '', origin: source_name, parser: parser) }
34
34
 
35
35
  before { $stderr = catcher }
36
36
 
@@ -61,7 +61,7 @@ RSpec.describe Reek::Source::SourceCode do
61
61
 
62
62
  context 'with a Parser::SyntaxError' do
63
63
  let(:error_class) { Parser::SyntaxError }
64
- let(:diagnostic) { double('diagnostic', message: error_message) }
64
+ let(:diagnostic) { instance_double('Parser::Diagnostic', message: error_message) }
65
65
 
66
66
  before do
67
67
  allow(parser).to receive(:parse_with_comments).
@@ -9,19 +9,23 @@ RSpec.describe Reek::Source::SourceLocator do
9
9
  let(:path) { SAMPLES_PATH.join('source_with_hidden_directories') }
10
10
 
11
11
  let(:expected_paths) do
12
- [SAMPLES_PATH.join('source_with_hidden_directories/uncommunicative_parameter_name.rb')]
12
+ [path.join('uncommunicative_parameter_name.rb')]
13
13
  end
14
14
 
15
15
  let(:paths_that_are_expected_to_be_ignored) do
16
- [SAMPLES_PATH.join('source_with_hidden_directories/.hidden/\
17
- uncommunicative_parameter_nameicative_method_name.rb')]
16
+ [path.join('.hidden/uncommunicative_method_name.rb')]
18
17
  end
19
18
 
20
19
  it 'does not scan hidden directories' do
21
20
  sources = described_class.new([path]).sources
22
21
 
23
22
  expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
24
- expect(sources).to eq expected_paths
23
+ end
24
+
25
+ it 'scans directories that are not hidden' do
26
+ sources = described_class.new([path]).sources
27
+
28
+ expect(sources).to match_array expected_paths
25
29
  end
26
30
  end
27
31
 
@@ -32,42 +36,50 @@ RSpec.describe Reek::Source::SourceLocator do
32
36
 
33
37
  let(:path) { SAMPLES_PATH.join('source_with_exclude_paths') }
34
38
 
39
+ let(:expected_paths) do
40
+ [path.join('nested/uncommunicative_parameter_name.rb')]
41
+ end
42
+
35
43
  let(:paths_that_are_expected_to_be_ignored) do
36
44
  [
37
- SAMPLES_PATH.join('source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb'),
38
- SAMPLES_PATH.join('source_with_exclude_paths/nested/' \
39
- 'ignore_me_as_well/irresponsible_module.rb')
45
+ path.join('ignore_me/uncommunicative_method_name.rb'),
46
+ path.join('nested/ignore_me_as_well/irresponsible_module.rb')
40
47
  ]
41
48
  end
42
49
 
43
50
  it 'does not use excluded paths' do
44
51
  sources = described_class.new([path], configuration: configuration).sources
45
52
  expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
53
+ end
46
54
 
47
- expect(sources).to eq [
48
- SAMPLES_PATH.join('source_with_exclude_paths/nested/uncommunicative_parameter_name.rb')
49
- ]
55
+ it 'scans directories that are not excluded' do
56
+ sources = described_class.new([path], configuration: configuration).sources
57
+ expect(sources).to eq expected_paths
50
58
  end
51
59
  end
52
60
 
53
61
  context 'non-Ruby paths' do
54
62
  let(:path) { SAMPLES_PATH.join('source_with_non_ruby_files') }
55
63
  let(:expected_sources) do
56
- [SAMPLES_PATH.join('source_with_non_ruby_files/uncommunicative_parameter_name.rb')]
64
+ [path.join('uncommunicative_parameter_name.rb')]
57
65
  end
58
66
  let(:paths_that_are_expected_to_be_ignored) do
59
67
  [
60
- SAMPLES_PATH.join('source_with_non_ruby_files/gibberish'),
61
- SAMPLES_PATH.join('source_with_non_ruby_files/python_source.py')
68
+ path.join('gibberish'),
69
+ path.join('python_source.py')
62
70
  ]
63
71
  end
64
72
 
65
- it 'does only use Ruby source paths' do
73
+ it 'uses Ruby source paths' do
66
74
  sources = described_class.new([path]).sources
67
75
 
68
- expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
76
+ expect(sources).to include(*expected_sources)
77
+ end
69
78
 
70
- expect(sources).to eq expected_sources
79
+ it 'does not use non-Ruby source paths' do
80
+ sources = described_class.new([path]).sources
81
+
82
+ expect(sources).not_to include(*paths_that_are_expected_to_be_ignored)
71
83
  end
72
84
  end
73
85
 
@@ -77,10 +89,15 @@ RSpec.describe Reek::Source::SourceLocator do
77
89
  end
78
90
 
79
91
  it 'expands it correctly' do
92
+ sources_for_dot = described_class.new([Pathname.new('.')]).sources
93
+
94
+ expect(sources_for_dot).to include(*expected_sources)
95
+ end
96
+
97
+ it 'ignores the trailing slash' do
80
98
  sources_for_dot = described_class.new([Pathname.new('.')]).sources
81
99
  sources_for_dot_slash = described_class.new([Pathname.new('./')]).sources
82
100
 
83
- expect(sources_for_dot).to include(*expected_sources)
84
101
  expect(sources_for_dot).to eq(sources_for_dot_slash)
85
102
  end
86
103
  end
@@ -24,7 +24,7 @@ RSpec.describe Reek::Spec::ShouldReekOf do
24
24
  describe 'different sources of input' do
25
25
  context 'checking code in a string' do
26
26
  let(:clean_code) { 'def good() true; end' }
27
- let(:matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName, name: 'y') }
27
+ let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
28
28
  let(:smelly_code) { 'def x() y = 4; end' }
29
29
 
30
30
  it 'matches a smelly String' do
@@ -42,7 +42,7 @@ RSpec.describe Reek::Spec::ShouldReekOf do
42
42
  end
43
43
 
44
44
  context 'checking code in a File' do
45
- let(:matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeMethodName, name: 'x') }
45
+ let(:matcher) { described_class.new(:UncommunicativeMethodName, name: 'x') }
46
46
 
47
47
  it 'matches a smelly file' do
48
48
  expect(matcher.matches?(SMELLY_FILE)).to be_truthy
@@ -56,7 +56,7 @@ RSpec.describe Reek::Spec::ShouldReekOf do
56
56
 
57
57
  describe 'smell types and smell details' do
58
58
  context 'passing in smell_details with unknown parameter name' do
59
- let(:matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName, foo: 'y') }
59
+ let(:matcher) { described_class.new(:UncommunicativeVariableName, foo: 'y') }
60
60
  let(:smelly_code) { 'def x() y = 4; end' }
61
61
 
62
62
  it 'raises ArgumentError' do
@@ -65,7 +65,7 @@ RSpec.describe Reek::Spec::ShouldReekOf do
65
65
  end
66
66
 
67
67
  context 'both are matching' do
68
- let(:matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName, name: 'y') }
68
+ let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
69
69
  let(:smelly_code) { 'def x() y = 4; end' }
70
70
 
71
71
  it 'is truthy' do
@@ -76,8 +76,8 @@ RSpec.describe Reek::Spec::ShouldReekOf do
76
76
  context 'no smell_type is matching' do
77
77
  let(:smelly_code) { 'def dummy() y = 4; end' }
78
78
 
79
- let(:falsey_matcher) { Reek::Spec::ShouldReekOf.new(:FeatureEnvy, name: 'y') }
80
- let(:truthy_matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName, name: 'y') }
79
+ let(:falsey_matcher) { described_class.new(:FeatureEnvy, name: 'y') }
80
+ let(:truthy_matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
81
81
 
82
82
  it 'is falsey' do
83
83
  expect(falsey_matcher.matches?(smelly_code)).to be_falsey
@@ -100,7 +100,7 @@ RSpec.describe Reek::Spec::ShouldReekOf do
100
100
 
101
101
  context 'smell type is matching but smell details are not' do
102
102
  let(:smelly_code) { 'def double_thing() @other.thing.foo + @other.thing.foo end' }
103
- let(:matcher) { Reek::Spec::ShouldReekOf.new(:DuplicateMethodCall, name: 'foo', count: 15) }
103
+ let(:matcher) { described_class.new(:DuplicateMethodCall, name: 'foo', count: 15) }
104
104
 
105
105
  it 'is falsey' do
106
106
  expect(matcher.matches?(smelly_code)).to be_falsey
@@ -130,15 +130,20 @@ RSpec.describe Reek::Spec::ShouldReekOf do
130
130
  end
131
131
  end
132
132
 
133
- it 'enables the smell detector to match automatically' do
134
- default_config = Reek::Smells::UnusedPrivateMethod.default_config
135
- expect(default_config[Reek::Smells::SmellConfiguration::ENABLED_KEY]).to be_falsy
133
+ context 'for a smell that is disabled by default' do
134
+ before do
135
+ default_config = Reek::Smells::UnusedPrivateMethod.default_config
136
+ expect(default_config[Reek::Smells::SmellConfiguration::ENABLED_KEY]).to be_falsy
137
+ end
136
138
 
137
- expect('class C; private; def foo; end; end').to reek_of(:UnusedPrivateMethod)
139
+ it 'enables the smell detector to match automatically' do
140
+ src = 'class C; private; def foo; end; end'
141
+ expect(src).to reek_of(:UnusedPrivateMethod)
142
+ end
138
143
  end
139
144
 
140
145
  describe '#with_config' do
141
- let(:matcher) { Reek::Spec::ShouldReekOf.new(:UncommunicativeVariableName) }
146
+ let(:matcher) { described_class.new(:UncommunicativeVariableName) }
142
147
  let(:configured_matcher) { matcher.with_config('accept' => 'x') }
143
148
 
144
149
  it 'uses the passed-in configuration for matching' do
@@ -2,14 +2,14 @@ require_relative '../../spec_helper'
2
2
  require_lib 'reek/spec'
3
3
 
4
4
  RSpec.describe Reek::Spec::ShouldReekOnlyOf do
5
- let(:examiner) { double('examiner').as_null_object }
5
+ let(:examiner) { instance_double('Reek::Examiner').as_null_object }
6
6
  let(:expected_context_name) { 'SmellyClass#big_method' }
7
7
  let(:expected_smell_type) { :NestedIterators }
8
- let(:matcher) { Reek::Spec::ShouldReekOnlyOf.new(expected_smell_type) }
8
+ let(:matcher) { described_class.new(expected_smell_type) }
9
9
  let(:matcher_matches) { matcher.matches_examiner?(examiner) }
10
10
 
11
11
  before do
12
- expect(examiner).to receive(:smells) { smells }
12
+ allow(examiner).to receive(:smells) { smells }
13
13
  matcher_matches
14
14
  end
15
15
 
@@ -21,7 +21,7 @@ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
21
21
  context 'when a match was expected' do
22
22
  let(:source) { 'the_path/to_a/source_file.rb' }
23
23
 
24
- before { expect(examiner).to receive(:description).and_return(source) }
24
+ before { allow(examiner).to receive(:description).and_return(source) }
25
25
 
26
26
  it 'reports the source' do
27
27
  expect(matcher.failure_message).to match(source)
@@ -91,7 +91,7 @@ RSpec.describe Reek::Spec::ShouldReekOnlyOf do
91
91
 
92
92
  it 'reports the source when no match was expected' do
93
93
  source = 'the_path/to_a/source_file.rb'
94
- expect(examiner).to receive(:description).and_return(source)
94
+ allow(examiner).to receive(:description).and_return(source)
95
95
  expect(matcher.failure_message_when_negated).to match(source)
96
96
  end
97
97
  end
@@ -3,7 +3,7 @@ require_lib 'reek/spec'
3
3
 
4
4
  RSpec.describe Reek::Spec::ShouldReek do
5
5
  describe 'checking code in a string' do
6
- let(:matcher) { Reek::Spec::ShouldReek.new }
6
+ let(:matcher) { described_class.new }
7
7
  let(:clean_code) { 'def good() true; end' }
8
8
  let(:smelly_code) { 'def x() y = 4; end' }
9
9
 
@@ -23,7 +23,7 @@ RSpec.describe Reek::Spec::ShouldReek do
23
23
 
24
24
  describe 'checking code in a File' do
25
25
  context 'matcher without masking' do
26
- let(:matcher) { Reek::Spec::ShouldReek.new }
26
+ let(:matcher) { described_class.new }
27
27
 
28
28
  it 'matches a smelly File' do
29
29
  expect(matcher.matches?(SMELLY_FILE)).to be_truthy
@@ -42,7 +42,7 @@ RSpec.describe Reek::Spec::ShouldReek do
42
42
  context 'matcher without masking' do
43
43
  let(:path) { CONFIG_PATH.join('full_mask.reek') }
44
44
  let(:configuration) { test_configuration_for(path) }
45
- let(:matcher) { Reek::Spec::ShouldReek.new(configuration: configuration) }
45
+ let(:matcher) { described_class.new(configuration: configuration) }
46
46
 
47
47
  it 'masks smells using the relevant configuration' do
48
48
  expect(matcher.matches?(SMELLY_FILE)).to be_falsey
@@ -33,13 +33,15 @@ RSpec.describe Reek::TreeDresser do
33
33
  end
34
34
 
35
35
  it 'dresses `def` nodes properly' do
36
- expect(def_node).to be_a Reek::AST::SexpExtensions::DefNode
37
- expect(def_node).to be_a Reek::AST::SexpExtensions::MethodNodeBase
36
+ expect(def_node).
37
+ to be_a(Reek::AST::SexpExtensions::DefNode).
38
+ and be_a(Reek::AST::SexpExtensions::MethodNodeBase)
38
39
  end
39
40
 
40
41
  it 'dresses `args` nodes properly' do
41
- expect(args_node).to be_a Reek::AST::SexpExtensions::ArgsNode
42
- expect(args_node).to be_a Reek::AST::SexpExtensions::NestedAssignables
42
+ expect(args_node).
43
+ to be_a(Reek::AST::SexpExtensions::ArgsNode).
44
+ and be_a(Reek::AST::SexpExtensions::NestedAssignables)
43
45
  end
44
46
 
45
47
  it 'dresses `send` nodes properly' do
@@ -81,6 +81,7 @@ RSpec.configure do |config|
81
81
 
82
82
  config.mock_with :rspec do |mocks|
83
83
  mocks.verify_partial_doubles = true
84
+ mocks.verify_doubled_constant_names = true
84
85
  end
85
86
 
86
87
  # Avoid infinitely running tests. This is mainly useful when running mutant.
@@ -93,6 +94,8 @@ RSpec.configure do |config|
93
94
  end
94
95
  end
95
96
 
97
+ RSpec::Matchers.define_negated_matcher :not_reek_of, :reek_of
98
+
96
99
  private
97
100
 
98
101
  def require_lib(path)
@@ -1,5 +1,11 @@
1
- require 'rubocop/rake_task'
1
+ begin
2
+ require 'rubocop/rake_task'
2
3
 
3
- RuboCop::RakeTask.new do |task|
4
- task.options << '--display-cop-names'
4
+ RuboCop::RakeTask.new do |task|
5
+ task.options << '--display-cop-names'
6
+ end
7
+ rescue LoadError
8
+ task :rubocop do
9
+ puts 'Install rubocop to run its rake tasks'
10
+ end
5
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reek
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.1
4
+ version: 4.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Rutherford
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-09-13 00:00:00.000000000 Z
14
+ date: 2016-09-21 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: codeclimate-engine-rb
@@ -155,6 +155,7 @@ files:
155
155
  - features/configuration_files/reject_setting.feature
156
156
  - features/configuration_files/unused_private_method.feature
157
157
  - features/configuration_loading.feature
158
+ - features/configuration_via_source_comments/erroneous_source_comments.feature
158
159
  - features/programmatic_access.feature
159
160
  - features/rake_task/rake_task.feature
160
161
  - features/reports/json.feature
@@ -219,6 +220,7 @@ files:
219
220
  - lib/reek/context/statement_counter.rb
220
221
  - lib/reek/context/visibility_tracker.rb
221
222
  - lib/reek/context_builder.rb
223
+ - lib/reek/errors.rb
222
224
  - lib/reek/examiner.rb
223
225
  - lib/reek/rake/task.rb
224
226
  - lib/reek/report.rb