reek 4.7.3 → 4.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -12
  3. data/.rubocop.yml +1 -0
  4. data/.travis.yml +4 -2
  5. data/CHANGELOG.md +10 -0
  6. data/Gemfile +3 -3
  7. data/README.md +19 -4
  8. data/lib/reek/ast/node.rb +37 -49
  9. data/lib/reek/ast/reference_collector.rb +2 -4
  10. data/lib/reek/ast/sexp_extensions/case.rb +1 -1
  11. data/lib/reek/ast/sexp_extensions/if.rb +8 -1
  12. data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
  13. data/lib/reek/ast/sexp_extensions/methods.rb +3 -5
  14. data/lib/reek/configuration/configuration_file_finder.rb +3 -3
  15. data/lib/reek/context/code_context.rb +4 -7
  16. data/lib/reek/context/method_context.rb +5 -10
  17. data/lib/reek/context/module_context.rb +3 -3
  18. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +9 -9
  19. data/lib/reek/errors/bad_detector_in_comment_error.rb +7 -7
  20. data/lib/reek/errors/base_error.rb +3 -0
  21. data/lib/reek/errors/encoding_error.rb +16 -11
  22. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +7 -7
  23. data/lib/reek/errors/incomprehensible_source_error.rb +20 -22
  24. data/lib/reek/examiner.rb +18 -14
  25. data/lib/reek/logging_error_handler.rb +7 -5
  26. data/lib/reek/smell_detectors/class_variable.rb +3 -10
  27. data/lib/reek/smell_detectors/duplicate_method_call.rb +1 -1
  28. data/lib/reek/smell_detectors/instance_variable_assumption.rb +1 -9
  29. data/lib/reek/smell_detectors/manual_dispatch.rb +1 -1
  30. data/lib/reek/smell_detectors/module_initialize.rb +1 -1
  31. data/lib/reek/smell_detectors/nested_iterators.rb +2 -1
  32. data/lib/reek/smell_detectors/too_many_constants.rb +1 -1
  33. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +2 -2
  34. data/lib/reek/smell_detectors/utility_function.rb +1 -1
  35. data/lib/reek/source/source_code.rb +9 -23
  36. data/lib/reek/version.rb +1 -1
  37. data/reek.gemspec +2 -2
  38. data/spec/factories/factories.rb +2 -13
  39. data/spec/reek/ast/node_spec.rb +98 -5
  40. data/spec/reek/ast/reference_collector_spec.rb +1 -1
  41. data/spec/reek/ast/sexp_extensions_spec.rb +2 -2
  42. data/spec/reek/cli/application_spec.rb +39 -41
  43. data/spec/reek/cli/command/todo_list_command_spec.rb +2 -2
  44. data/spec/reek/code_comment_spec.rb +32 -32
  45. data/spec/reek/configuration/app_configuration_spec.rb +3 -3
  46. data/spec/reek/configuration/configuration_file_finder_spec.rb +1 -1
  47. data/spec/reek/configuration/directory_directives_spec.rb +3 -3
  48. data/spec/reek/configuration/excluded_paths_spec.rb +1 -1
  49. data/spec/reek/context/code_context_spec.rb +59 -95
  50. data/spec/reek/context/ghost_context_spec.rb +1 -1
  51. data/spec/reek/context/root_context_spec.rb +1 -1
  52. data/spec/reek/errors/base_error_spec.rb +13 -0
  53. data/spec/reek/examiner_spec.rb +72 -29
  54. data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -80
  55. data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
  56. data/spec/reek/report/xml_report_spec.rb +2 -2
  57. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +2 -2
  58. data/spec/reek/smell_detectors/class_variable_spec.rb +26 -32
  59. data/spec/reek/smell_detectors/control_parameter_spec.rb +34 -4
  60. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +3 -3
  61. data/spec/reek/smell_detectors/module_initialize_spec.rb +14 -0
  62. data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
  63. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +3 -3
  64. data/spec/reek/smell_detectors/unused_parameters_spec.rb +3 -3
  65. data/spec/reek/smell_detectors/unused_private_method_spec.rb +9 -9
  66. data/spec/reek/smell_detectors/utility_function_spec.rb +5 -5
  67. data/spec/reek/smell_warning_spec.rb +8 -8
  68. data/spec/reek/source/source_code_spec.rb +5 -25
  69. data/spec/reek/source/source_locator_spec.rb +6 -6
  70. data/spec/reek/spec/should_reek_of_spec.rb +7 -7
  71. data/spec/reek/spec/should_reek_spec.rb +2 -2
  72. data/spec/reek/spec/smell_matcher_spec.rb +3 -3
  73. data/spec/reek/tree_dresser_spec.rb +11 -12
  74. data/spec/spec_helper.rb +3 -12
  75. metadata +10 -9
@@ -8,6 +8,6 @@ module Reek
8
8
  # @public
9
9
  module Version
10
10
  # @public
11
- STRING = '4.7.3'.freeze
11
+ STRING = '4.8.0'.freeze
12
12
  end
13
13
  end
@@ -21,6 +21,6 @@ Gem::Specification.new do |s|
21
21
  s.summary = 'Code smell detector for Ruby'
22
22
 
23
23
  s.add_runtime_dependency 'codeclimate-engine-rb', '~> 0.4.0'
24
- s.add_runtime_dependency 'parser', '< 2.5', '>= 2.4.0.0'
25
- s.add_runtime_dependency 'rainbow', '~> 2.0'
24
+ s.add_runtime_dependency 'parser', '< 2.6', '>= 2.5.0.0'
25
+ s.add_runtime_dependency 'rainbow', '~> 3.0'
26
26
  end
@@ -3,18 +3,7 @@ require_relative '../../lib/reek/smell_detectors/base_detector'
3
3
  require_relative '../../lib/reek/smell_warning'
4
4
  require_relative '../../lib/reek/cli/options'
5
5
 
6
- FactoryGirl.define do
7
- factory :method_context, class: Reek::Context::MethodContext do
8
- skip_create
9
- transient do
10
- source 'def foo; end'
11
- end
12
-
13
- initialize_with do
14
- new(nil, Reek::Source::SourceCode.from(source).syntax_tree)
15
- end
16
- end
17
-
6
+ FactoryBot.define do
18
7
  factory :smell_detector, class: Reek::SmellDetectors::BaseDetector do
19
8
  skip_create
20
9
  transient do
@@ -33,7 +22,7 @@ FactoryGirl.define do
33
22
  source 'dummy_file'
34
23
  lines [42]
35
24
  message 'smell warning message'
36
- parameters { {} }
25
+ parameters({})
37
26
 
38
27
  initialize_with do
39
28
  new(smell_detector,
@@ -2,6 +2,92 @@ require_relative '../../spec_helper'
2
2
  require_lib 'reek/ast/node'
3
3
 
4
4
  RSpec.describe Reek::AST::Node do
5
+ describe '#each_node' do
6
+ context 'with an empty module' do
7
+ let(:ast) do
8
+ src = 'module Emptiness; end'
9
+ Reek::Source::SourceCode.from(src).syntax_tree
10
+ end
11
+
12
+ it 'yields no calls' do
13
+ ast.each_node(:send, []) { |exp| raise "#{exp} yielded by empty module!" }
14
+ end
15
+
16
+ it 'yields one module' do
17
+ mods = 0
18
+ ast.each_node(:module, []) { |_exp| mods += 1 }
19
+ expect(mods).to eq(1)
20
+ end
21
+
22
+ it "yields the module's full AST" do
23
+ ast.each_node(:module, []) do |exp|
24
+ expect(exp).to eq(sexp(:module, sexp(:const, nil, :Emptiness), nil))
25
+ end
26
+ end
27
+
28
+ it 'returns an enumerator when no block is passed' do
29
+ expect(ast.each_node(:if)).to be_instance_of Enumerator
30
+ end
31
+ end
32
+
33
+ context 'with a nested element' do
34
+ let(:ast) do
35
+ src = "module Loneliness; def calloo; puts('hello') end; end"
36
+ Reek::Source::SourceCode.from(src).syntax_tree
37
+ end
38
+
39
+ it 'yields no ifs' do
40
+ ast.each_node(:if) { |exp| raise "#{exp} yielded by empty module!" }
41
+ end
42
+
43
+ it 'yields one module' do
44
+ expect(ast.each_node(:module).to_a.length).to eq(1)
45
+ end
46
+
47
+ it "yields the module's full AST" do
48
+ ast.each_node(:module) do |exp|
49
+ expect(exp).to eq sexp(:module,
50
+ sexp(:const, nil, :Loneliness),
51
+ sexp(:def, :calloo,
52
+ sexp(:args),
53
+ sexp(:send, nil, :puts, sexp(:str, 'hello'))))
54
+ end
55
+ end
56
+
57
+ it 'yields one method' do
58
+ expect(ast.each_node(:def).to_a.length).to eq(1)
59
+ end
60
+
61
+ it "yields the method's full AST" do
62
+ ast.each_node(:def, []) { |exp| expect(exp.children.first).to eq(:calloo) }
63
+ end
64
+
65
+ it 'ignores the call inside the method if the traversal is pruned' do
66
+ expect(ast.each_node(:send, [:def]).to_a).to be_empty
67
+ end
68
+ end
69
+
70
+ it 'finds 3 ifs in a class' do
71
+ src = <<-EOS
72
+ class Scrunch
73
+ def first
74
+ return @field == :sym ? 0 : 3;
75
+ end
76
+ def second
77
+ if @field == :sym
78
+ @other += " quarts"
79
+ end
80
+ end
81
+ def third
82
+ raise 'flu!' unless @field == :sym
83
+ end
84
+ end
85
+ EOS
86
+ ast = Reek::Source::SourceCode.from(src).syntax_tree
87
+ expect(ast.each_node(:if).to_a.length).to eq(3)
88
+ end
89
+ end
90
+
5
91
  describe '#format_to_ruby' do
6
92
  it 'returns #to_s if location is not present' do
7
93
  ast = sexp(:self)
@@ -56,7 +142,7 @@ RSpec.describe Reek::AST::Node do
56
142
  end
57
143
  end
58
144
 
59
- context 'hash' do
145
+ describe '#hash' do
60
146
  it 'hashes equal for equal sexps' do
61
147
  node1 = sexp(:def, :jim, sexp(:args), sexp(:send, sexp(:int, 4), :+, sexp(:send, nil, :fred)))
62
148
  node2 = sexp(:def, :jim, sexp(:args), sexp(:send, sexp(:int, 4), :+, sexp(:send, nil, :fred)))
@@ -77,7 +163,7 @@ RSpec.describe Reek::AST::Node do
77
163
  end
78
164
 
79
165
  describe '#line' do
80
- context 'source from file' do
166
+ context 'with source from a file' do
81
167
  let(:file) { SAMPLES_PATH.join('smelly.rb') }
82
168
  let(:ast) { Reek::Source::SourceCode.from(file).syntax_tree }
83
169
 
@@ -86,7 +172,7 @@ RSpec.describe Reek::AST::Node do
86
172
  end
87
173
  end
88
174
 
89
- context 'source from string' do
175
+ context 'with source from a string' do
90
176
  let(:source) { File.read(SAMPLES_PATH.join('smelly.rb')) }
91
177
  let(:ast) { Reek::Source::SourceCode.from(source).syntax_tree }
92
178
 
@@ -97,7 +183,7 @@ RSpec.describe Reek::AST::Node do
97
183
  end
98
184
 
99
185
  describe '#source' do
100
- context 'source from file' do
186
+ context 'with source from a file' do
101
187
  let(:file) { SAMPLES_PATH.join('smelly.rb') }
102
188
  let(:ast) { Reek::Source::SourceCode.from(file).syntax_tree }
103
189
 
@@ -106,7 +192,7 @@ RSpec.describe Reek::AST::Node do
106
192
  end
107
193
  end
108
194
 
109
- context 'source from string' do
195
+ context 'with source from a string' do
110
196
  let(:source) { File.read(SAMPLES_PATH.join('smelly.rb')) }
111
197
  let(:ast) { Reek::Source::SourceCode.from(source).syntax_tree }
112
198
 
@@ -115,4 +201,11 @@ RSpec.describe Reek::AST::Node do
115
201
  end
116
202
  end
117
203
  end
204
+
205
+ describe '#name' do
206
+ it 'returns #to_s if no override is present' do
207
+ ast = sexp(:foo)
208
+ expect(ast.name).to eq ast.to_s
209
+ end
210
+ end
118
211
  end
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
2
2
  require_lib 'reek/ast/reference_collector'
3
3
 
4
4
  RSpec.describe Reek::AST::ReferenceCollector do
5
- context 'counting refs to self' do
5
+ describe '#num_refs_to_self' do
6
6
  def refs_to_self(src)
7
7
  syntax_tree = Reek::Source::SourceCode.from(src).syntax_tree
8
8
  described_class.new(syntax_tree).num_refs_to_self
@@ -107,7 +107,7 @@ RSpec.describe Reek::AST::SexpExtensions::DefNode do
107
107
  end
108
108
 
109
109
  it 'finds nodes in the body with #body_nodes' do
110
- expect(node.body_nodes([:first])).to eq [sexp(:first)]
110
+ expect(node.body_nodes([:first]).to_a).to eq [sexp(:first)]
111
111
  end
112
112
  end
113
113
 
@@ -374,7 +374,7 @@ end
374
374
  RSpec.describe Reek::AST::SexpExtensions::LambdaNode do
375
375
  let(:node) { sexp(:lambda) }
376
376
 
377
- context '#name' do
377
+ describe '#name' do
378
378
  it 'returns :lambda' do
379
379
  expect(node.name).to eq 'lambda'
380
380
  end
@@ -32,58 +32,56 @@ RSpec.describe Reek::CLI::Application do
32
32
  expect(app.execute).to eq 'foo'
33
33
  end
34
34
 
35
- context 'when no source files given' do
36
- context 'and input was piped' do
37
- before do
38
- allow_any_instance_of(IO).to receive(:tty?).and_return(false)
39
- end
35
+ context 'when no source files given and input was piped' do
36
+ before do
37
+ allow_any_instance_of(IO).to receive(:tty?).and_return(false)
38
+ end
40
39
 
41
- it 'uses source form pipe' do
42
- app.execute
43
- expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
44
- with(sources: [$stdin],
45
- configuration: Reek::Configuration::AppConfiguration,
46
- options: Reek::CLI::Options)
47
- end
40
+ it 'uses source form pipe' do
41
+ app.execute
42
+ expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
43
+ with(sources: [$stdin],
44
+ configuration: Reek::Configuration::AppConfiguration,
45
+ options: Reek::CLI::Options)
46
+ end
47
+ end
48
+
49
+ context 'when no source files given and no input was piped' do
50
+ before do
51
+ allow_any_instance_of(IO).to receive(:tty?).and_return(true)
48
52
  end
49
53
 
50
- context 'and input was not piped' do
54
+ it 'uses working directory as source' do
55
+ expected_sources = Reek::Source::SourceLocator.new(['.']).sources
56
+ app.execute
57
+ expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
58
+ with(sources: expected_sources,
59
+ configuration: Reek::Configuration::AppConfiguration,
60
+ options: Reek::CLI::Options)
61
+ end
62
+
63
+ context 'when source files are excluded through configuration' do
64
+ let(:app) { described_class.new ['--config', 'some_file.reek'] }
65
+
51
66
  before do
52
- allow_any_instance_of(IO).to receive(:tty?).and_return(true)
67
+ allow(Reek::Configuration::AppConfiguration).
68
+ to receive(:from_path).
69
+ with(Pathname.new('some_file.reek')).
70
+ and_return configuration
53
71
  end
54
72
 
55
- it 'uses working directory as source' do
56
- expected_sources = Reek::Source::SourceLocator.new(['.']).sources
73
+ it 'uses configuration for excluded paths' do
74
+ expected_sources = Reek::Source::SourceLocator.
75
+ new(['.'], configuration: configuration).sources
76
+ expect(expected_sources).not_to include(path_excluded_in_configuration)
77
+
57
78
  app.execute
79
+
58
80
  expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
59
81
  with(sources: expected_sources,
60
- configuration: Reek::Configuration::AppConfiguration,
82
+ configuration: configuration,
61
83
  options: Reek::CLI::Options)
62
84
  end
63
-
64
- context 'when source files are excluded through configuration' do
65
- let(:app) { described_class.new ['--config', 'some_file.reek'] }
66
-
67
- before do
68
- allow(Reek::Configuration::AppConfiguration).
69
- to receive(:from_path).
70
- with(Pathname.new('some_file.reek')).
71
- and_return configuration
72
- end
73
-
74
- it 'uses configuration for excluded paths' do
75
- expected_sources = Reek::Source::SourceLocator.
76
- new(['.'], configuration: configuration).sources
77
- expect(expected_sources).not_to include(path_excluded_in_configuration)
78
-
79
- app.execute
80
-
81
- expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
82
- with(sources: expected_sources,
83
- configuration: configuration,
84
- options: Reek::CLI::Options)
85
- end
86
- end
87
85
  end
88
86
  end
89
87
 
@@ -21,7 +21,7 @@ RSpec.describe Reek::CLI::Command::TodoListCommand do
21
21
  allow(File).to receive(:write).with(described_class::FILE_NAME, String)
22
22
  end
23
23
 
24
- context 'smells found' do
24
+ context 'when smells are found' do
25
25
  let(:source_file) { SMELLY_FILE }
26
26
 
27
27
  it 'shows a proper message' do
@@ -44,7 +44,7 @@ RSpec.describe Reek::CLI::Command::TodoListCommand do
44
44
  end
45
45
  end
46
46
 
47
- context 'no smells found' do
47
+ context 'when no smells re found' do
48
48
  let(:source_file) { CLEAN_FILE }
49
49
 
50
50
  it 'shows a proper message' do
@@ -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) { FactoryGirl.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
@@ -14,33 +14,33 @@ RSpec.describe Reek::CodeComment do
14
14
  end
15
15
  end
16
16
 
17
- context 'comment checks' do
17
+ describe '#descriptive' do
18
18
  it 'rejects an empty comment' do
19
- comment = FactoryGirl.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 = FactoryGirl.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 = FactoryGirl.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 = FactoryGirl.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
- context 'good comment config' do
39
+ describe 'good comment config' do
40
40
  it 'parses hashed options' do
41
41
  comment = '# :reek:DuplicateMethodCall { enabled: false }'
42
- config = FactoryGirl.build(:code_comment,
43
- comment: comment).config
42
+ config = build(:code_comment,
43
+ comment: comment).config
44
44
 
45
45
  expect(config).to include('DuplicateMethodCall')
46
46
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -49,8 +49,8 @@ RSpec.describe Reek::CodeComment do
49
49
 
50
50
  it "supports hashed options with the legacy separator ':' after the smell detector" do
51
51
  comment = '# :reek:DuplicateMethodCall: { enabled: false }'
52
- config = FactoryGirl.build(:code_comment,
53
- comment: comment).config
52
+ config = build(:code_comment,
53
+ comment: comment).config
54
54
 
55
55
  expect(config).to include('DuplicateMethodCall')
56
56
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -62,7 +62,7 @@ RSpec.describe Reek::CodeComment do
62
62
  # :reek:DuplicateMethodCall { enabled: false }
63
63
  # :reek:NestedIterators { enabled: true }
64
64
  EOF
65
- config = FactoryGirl.build(:code_comment, comment: comment).config
65
+ config = build(:code_comment, comment: comment).config
66
66
 
67
67
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
68
68
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -75,7 +75,7 @@ RSpec.describe Reek::CodeComment do
75
75
  comment = <<-EOF
76
76
  #:reek:DuplicateMethodCall { enabled: false } and :reek:NestedIterators { enabled: true }
77
77
  EOF
78
- config = FactoryGirl.build(:code_comment, comment: comment).config
78
+ config = build(:code_comment, comment: comment).config
79
79
 
80
80
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
81
81
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -86,7 +86,7 @@ RSpec.describe Reek::CodeComment do
86
86
 
87
87
  it 'parses multiple unhashed options on the same line' do
88
88
  comment = '# :reek:DuplicateMethodCall and :reek:NestedIterators'
89
- config = FactoryGirl.build(:code_comment, comment: comment).config
89
+ config = build(:code_comment, comment: comment).config
90
90
 
91
91
  expect(config).to include('DuplicateMethodCall', 'NestedIterators')
92
92
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -97,7 +97,7 @@ RSpec.describe Reek::CodeComment do
97
97
 
98
98
  it 'disables the smell if no options are specifed' do
99
99
  comment = '# :reek:DuplicateMethodCall'
100
- config = FactoryGirl.build(:code_comment, comment: comment).config
100
+ config = build(:code_comment, comment: comment).config
101
101
 
102
102
  expect(config).to include('DuplicateMethodCall')
103
103
  expect(config['DuplicateMethodCall']).to include('enabled')
@@ -105,8 +105,8 @@ RSpec.describe Reek::CodeComment do
105
105
  end
106
106
 
107
107
  it 'ignores smells after a space' do
108
- config = FactoryGirl.build(:code_comment,
109
- comment: '# :reek: DuplicateMethodCall').config
108
+ config = build(:code_comment,
109
+ comment: '# :reek: DuplicateMethodCall').config
110
110
  expect(config).not_to include('DuplicateMethodCall')
111
111
  end
112
112
 
@@ -117,7 +117,7 @@ RSpec.describe Reek::CodeComment do
117
117
  # :reek:NestedIterators { enabled: true }
118
118
  # comment
119
119
  EOF
120
- comment = FactoryGirl.build(:code_comment, comment: original_comment)
120
+ comment = build(:code_comment, comment: original_comment)
121
121
 
122
122
  expect(comment.send(:sanitized_comment)).to eq('Actual comment')
123
123
  end
@@ -125,66 +125,66 @@ RSpec.describe Reek::CodeComment do
125
125
  end
126
126
 
127
127
  RSpec.describe Reek::CodeComment::CodeCommentValidator do
128
- context 'bad detector' do
128
+ context 'when the comment contains an unknown detector name' do
129
129
  it 'raises BadDetectorInCommentError' do
130
130
  expect do
131
- FactoryGirl.build(:code_comment,
132
- comment: '# :reek:DoesNotExist')
131
+ build(:code_comment,
132
+ comment: '# :reek:DoesNotExist')
133
133
  end.to raise_error(Reek::Errors::BadDetectorInCommentError)
134
134
  end
135
135
  end
136
136
 
137
- context 'unparsable detector configuration' do
137
+ context 'when the comment contains an unparsable detector configuration' do
138
138
  it 'raises GarbageDetectorConfigurationInCommentError' do
139
139
  expect do
140
140
  comment = '# :reek:UncommunicativeMethodName { thats: a: bad: config }'
141
- FactoryGirl.build(:code_comment, comment: comment)
141
+ build(:code_comment, comment: comment)
142
142
  end.to raise_error(Reek::Errors::GarbageDetectorConfigurationInCommentError)
143
143
  end
144
144
  end
145
145
 
146
146
  describe 'validating configuration keys' do
147
- context 'basic options mispelled' do
147
+ context 'when basic options are mispelled' do
148
148
  it 'raises BadDetectorConfigurationKeyInCommentError' do
149
149
  expect do
150
150
  # exclude -> exlude and enabled -> nabled
151
151
  comment = '# :reek:UncommunicativeMethodName { exlude: alfa, nabled: true }'
152
- FactoryGirl.build(:code_comment, comment: comment)
152
+ build(:code_comment, comment: comment)
153
153
  end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
154
154
  end
155
155
  end
156
156
 
157
- context 'basic options not mispelled' do
157
+ context 'when basic options are not mispelled' do
158
158
  it 'does not raise' do
159
159
  expect do
160
160
  comment = '# :reek:UncommunicativeMethodName { exclude: alfa, enabled: true }'
161
- FactoryGirl.build(:code_comment, comment: comment)
161
+ build(:code_comment, comment: comment)
162
162
  end.not_to raise_error
163
163
  end
164
164
 
165
165
  it 'does not raise on regexps' do
166
166
  expect do
167
167
  comment = '# :reek:UncommunicativeMethodName { exclude: !ruby/regexp /alfa/ }'
168
- FactoryGirl.build(:code_comment, comment: comment)
168
+ build(:code_comment, comment: comment)
169
169
  end.not_to raise_error
170
170
  end
171
171
  end
172
172
 
173
- context 'unknown custom options' do
173
+ context 'when unknown custom options are specified' do
174
174
  it 'raises BadDetectorConfigurationKeyInCommentError' do
175
175
  expect do
176
176
  # max_copies -> mx_copies and min_clump_size -> mn_clump_size
177
177
  comment = '# :reek:DataClump { mx_copies: 4, mn_clump_size: 3 }'
178
- FactoryGirl.build(:code_comment, comment: comment)
178
+ build(:code_comment, comment: comment)
179
179
  end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
180
180
  end
181
181
  end
182
182
 
183
- context 'valid custom options' do
183
+ context 'when valid custom options are specified' do
184
184
  it 'does not raise' do
185
185
  expect do
186
186
  comment = '# :reek:DataClump { max_copies: 4, min_clump_size: 3 }'
187
- FactoryGirl.build(:code_comment, comment: comment)
187
+ build(:code_comment, comment: comment)
188
188
  end.not_to raise_error
189
189
  end
190
190
  end