reek 4.2.3 → 4.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +7 -6
- data/Gemfile +2 -2
- data/README.md +8 -15
- data/Rakefile +1 -1
- data/defaults.reek +1 -0
- data/features/command_line_interface/basic_usage.feature +8 -14
- data/features/command_line_interface/smell_selection.feature +4 -4
- data/features/command_line_interface/smells_count.feature +12 -14
- data/features/configuration_files/masking_smells.feature +31 -24
- data/features/configuration_loading.feature +15 -18
- data/features/programmatic_access.feature +7 -9
- data/features/rake_task/rake_task.feature +20 -24
- data/features/reports/json.feature +16 -28
- data/features/reports/reports.feature +56 -67
- data/features/reports/yaml.feature +13 -26
- data/features/samples.feature +3 -3
- data/features/step_definitions/sample_file_steps.rb +22 -156
- data/features/todo_list.feature +13 -14
- data/lib/reek/cli/options.rb +1 -1
- data/lib/reek/examiner.rb +45 -10
- data/lib/reek/smells/attribute.rb +3 -4
- data/lib/reek/smells/boolean_parameter.rb +2 -2
- data/lib/reek/smells/class_variable.rb +1 -1
- data/lib/reek/smells/control_parameter.rb +4 -4
- data/lib/reek/smells/data_clump.rb +2 -3
- data/lib/reek/smells/duplicate_method_call.rb +1 -1
- data/lib/reek/smells/feature_envy.rb +2 -2
- data/lib/reek/smells/irresponsible_module.rb +2 -3
- data/lib/reek/smells/long_parameter_list.rb +1 -1
- data/lib/reek/smells/long_yield_list.rb +1 -1
- data/lib/reek/smells/module_initialize.rb +1 -1
- data/lib/reek/smells/nested_iterators.rb +2 -2
- data/lib/reek/smells/nil_check.rb +1 -1
- data/lib/reek/smells/prima_donna_method.rb +5 -2
- data/lib/reek/smells/repeated_conditional.rb +1 -1
- data/lib/reek/smells/smell_detector.rb +1 -1
- data/lib/reek/smells/smell_warning.rb +6 -5
- data/lib/reek/smells/subclassed_from_core_class.rb +3 -3
- data/lib/reek/smells/too_many_constants.rb +1 -1
- data/lib/reek/smells/too_many_instance_variables.rb +1 -1
- data/lib/reek/smells/too_many_methods.rb +1 -1
- data/lib/reek/smells/too_many_statements.rb +1 -1
- data/lib/reek/smells/uncommunicative_method_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_module_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_parameter_name.rb +1 -1
- data/lib/reek/smells/uncommunicative_variable_name.rb +1 -1
- data/lib/reek/smells/unused_parameters.rb +1 -1
- data/lib/reek/smells/unused_private_method.rb +1 -1
- data/lib/reek/smells/utility_function.rb +2 -3
- data/lib/reek/spec/should_reek_of.rb +14 -1
- data/lib/reek/version.rb +1 -1
- data/samples/checkstyle.xml +7 -0
- data/samples/clean.rb +6 -0
- data/samples/configuration/.reek +0 -0
- data/samples/configuration/corrupt.reek +1 -0
- data/samples/configuration/empty.reek +0 -0
- data/samples/configuration/full_configuration.reek +9 -0
- data/{spec/samples/configuration/simple_configuration.reek → samples/configuration/full_mask.reek} +2 -2
- data/samples/configuration/non_public_modifiers_mask.reek +3 -0
- data/samples/configuration/partial_mask.reek +3 -0
- data/samples/configuration/with_excluded_paths.reek +4 -0
- data/{spec/samples → samples}/exceptions.reek +0 -0
- data/{spec/samples → samples}/inline.rb +0 -0
- data/{spec/samples → samples}/optparse.rb +0 -0
- data/samples/paths.rb +4 -0
- data/{spec/samples → samples}/redcloth.rb +0 -0
- data/samples/smelly.rb +7 -0
- data/samples/smelly_with_inline_mask.rb +8 -0
- data/samples/smelly_with_modifiers.rb +12 -0
- data/{spec/samples → samples}/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -0
- data/{spec/samples → samples}/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -0
- data/{spec/samples → samples}/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -0
- data/{spec/samples → samples}/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -0
- data/{spec/samples → samples}/source_with_hidden_directories/uncommunicative_parameter_name.rb +0 -0
- data/{spec/samples → samples}/source_with_non_ruby_files/gibberish +0 -0
- data/{spec/samples → samples}/source_with_non_ruby_files/python_source.py +0 -0
- data/{spec/samples → samples}/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -0
- data/spec/reek/cli/application_spec.rb +1 -1
- data/spec/reek/cli/command/report_command_spec.rb +2 -5
- data/spec/reek/configuration/app_configuration_spec.rb +10 -8
- data/spec/reek/configuration/configuration_file_finder_spec.rb +24 -17
- data/spec/reek/examiner_spec.rb +84 -5
- data/spec/reek/report/json_report_spec.rb +1 -3
- data/spec/reek/report/xml_report_spec.rb +2 -3
- data/spec/reek/report/yaml_report_spec.rb +0 -2
- data/spec/reek/smells/attribute_spec.rb +21 -10
- data/spec/reek/smells/boolean_parameter_spec.rb +13 -12
- data/spec/reek/smells/class_variable_spec.rb +4 -4
- data/spec/reek/smells/control_parameter_spec.rb +25 -18
- data/spec/reek/smells/data_clump_spec.rb +5 -5
- data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
- data/spec/reek/smells/feature_envy_spec.rb +8 -2
- data/spec/reek/smells/irresponsible_module_spec.rb +16 -14
- data/spec/reek/smells/long_parameter_list_spec.rb +5 -1
- data/spec/reek/smells/long_yield_list_spec.rb +5 -2
- data/spec/reek/smells/nested_iterators_spec.rb +37 -13
- data/spec/reek/smells/nil_check_spec.rb +50 -53
- data/spec/reek/smells/prima_donna_method_spec.rb +9 -1
- data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smells/too_many_methods_spec.rb +4 -4
- data/spec/reek/smells/too_many_statements_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +3 -3
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +3 -3
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +3 -3
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +3 -3
- data/spec/reek/smells/utility_function_spec.rb +12 -8
- data/spec/reek/source/source_locator_spec.rb +5 -1
- data/spec/reek/spec/should_reek_of_spec.rb +20 -13
- data/spec/reek/spec/should_reek_spec.rb +6 -11
- data/spec/spec_helper.rb +2 -2
- metadata +28 -36
- data/spec/samples/all_but_one_masked/clean_one.rb +0 -7
- data/spec/samples/all_but_one_masked/dirty.rb +0 -8
- data/spec/samples/all_but_one_masked/masked.reek +0 -9
- data/spec/samples/checkstyle.xml +0 -13
- data/spec/samples/clean_due_to_masking/clean_one.rb +0 -7
- data/spec/samples/clean_due_to_masking/clean_three.rb +0 -7
- data/spec/samples/clean_due_to_masking/clean_two.rb +0 -7
- data/spec/samples/clean_due_to_masking/dirty_one.rb +0 -7
- data/spec/samples/clean_due_to_masking/dirty_two.rb +0 -7
- data/spec/samples/clean_due_to_masking/masked.reek +0 -11
- data/spec/samples/configuration/full_configuration.reek +0 -9
- data/spec/samples/configuration/with_excluded_paths.reek +0 -4
- data/spec/samples/masked_by_dotfile/.reek +0 -9
- data/spec/samples/masked_by_dotfile/dirty.rb +0 -8
- data/spec/samples/no_config_file/dirty.rb +0 -8
- data/spec/samples/three_clean_files/clean_one.rb +0 -7
- data/spec/samples/three_clean_files/clean_three.rb +0 -7
- data/spec/samples/three_clean_files/clean_two.rb +0 -7
- data/spec/samples/two_smelly_files/dirty_one.rb +0 -8
- data/spec/samples/two_smelly_files/dirty_two.rb +0 -8
|
@@ -26,7 +26,7 @@ RSpec.shared_examples_for 'a data clump detector' do
|
|
|
26
26
|
end
|
|
27
27
|
EOS
|
|
28
28
|
ctx = Reek::Context::ModuleContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
29
|
-
build(:smell_detector, smell_type: :DataClump).
|
|
29
|
+
build(:smell_detector, smell_type: :DataClump).sniff(ctx)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it 'records only the one smell' do
|
|
@@ -41,10 +41,6 @@ RSpec.shared_examples_for 'a data clump detector' do
|
|
|
41
41
|
expect(smells[0].parameters[:count]).to eq(3)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
it 'reports all methods' do
|
|
45
|
-
expect(smells[0].parameters[:methods]).to eq([:first, :second, :third])
|
|
46
|
-
end
|
|
47
|
-
|
|
48
44
|
it 'reports the declaration line numbers' do
|
|
49
45
|
expect(smells[0].lines).to eq([2, 3, 4])
|
|
50
46
|
end
|
|
@@ -56,6 +52,10 @@ RSpec.shared_examples_for 'a data clump detector' do
|
|
|
56
52
|
it 'reports the context fq name' do
|
|
57
53
|
expect(smells[0].context).to eq(module_name)
|
|
58
54
|
end
|
|
55
|
+
|
|
56
|
+
it 'has the right message' do
|
|
57
|
+
expect(smells[0].message).to eq('takes parameters [pa, pb] to 3 methods')
|
|
58
|
+
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
it 'reports 3 swapped pairs' do
|
|
@@ -17,7 +17,7 @@ RSpec.describe Reek::Smells::DuplicateMethodCall do
|
|
|
17
17
|
end
|
|
18
18
|
EOS
|
|
19
19
|
ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
20
|
-
smells = detector.
|
|
20
|
+
smells = detector.sniff(ctx)
|
|
21
21
|
expect(smells.length).to eq(1)
|
|
22
22
|
smells.first
|
|
23
23
|
end
|
|
@@ -235,10 +235,16 @@ RSpec.describe Reek::Smells::FeatureEnvy do
|
|
|
235
235
|
|
|
236
236
|
it_should_behave_like 'common fields set correctly'
|
|
237
237
|
|
|
238
|
-
it 'reports the
|
|
238
|
+
it 'reports the name' do
|
|
239
239
|
expect(warning.parameters[:name]).to eq(receiver)
|
|
240
|
-
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'reports the lines' do
|
|
241
243
|
expect(warning.lines).to eq([2, 4, 5])
|
|
242
244
|
end
|
|
245
|
+
|
|
246
|
+
it 'has the right message' do
|
|
247
|
+
expect(warning.message).to eq('refers to other more than self (maybe move it to another class?)')
|
|
248
|
+
end
|
|
243
249
|
end
|
|
244
250
|
end
|
|
@@ -6,12 +6,14 @@ require_relative 'smell_detector_shared'
|
|
|
6
6
|
RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
7
7
|
it 'reports a class without a comment' do
|
|
8
8
|
src = 'class BadClass; end'
|
|
9
|
-
expect(src).to reek_of :IrresponsibleModule,
|
|
9
|
+
expect(src).to reek_of :IrresponsibleModule,
|
|
10
|
+
lines: [1],
|
|
11
|
+
message: 'has no descriptive comment'
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
it 'reports a module without a comment' do
|
|
13
15
|
src = 'module BadClass; end'
|
|
14
|
-
expect(src).to reek_of
|
|
16
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'BadClass')
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
it 'does not report re-opened modules' do
|
|
@@ -39,7 +41,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
39
41
|
#
|
|
40
42
|
class BadClass; end
|
|
41
43
|
EOS
|
|
42
|
-
expect(src).to reek_of :
|
|
44
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'BadClass')
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
it 'reports a class with a preceding comment with intermittent material' do
|
|
@@ -50,7 +52,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
50
52
|
|
|
51
53
|
class Bar; end
|
|
52
54
|
EOS
|
|
53
|
-
expect(src).to reek_of(:IrresponsibleModule)
|
|
55
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Bar')
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
it 'reports a class with a trailing comment' do
|
|
@@ -58,12 +60,12 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
58
60
|
class BadClass
|
|
59
61
|
end # end BadClass
|
|
60
62
|
EOS
|
|
61
|
-
expect(src).to reek_of(:IrresponsibleModule)
|
|
63
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'BadClass')
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
it 'reports a fully qualified class name correctly' do
|
|
65
67
|
src = 'class Foo::Bar; end'
|
|
66
|
-
expect(src).to reek_of
|
|
68
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo::Bar')
|
|
67
69
|
end
|
|
68
70
|
|
|
69
71
|
it 'does not report modules used only as namespaces' do
|
|
@@ -102,7 +104,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
102
104
|
end
|
|
103
105
|
end
|
|
104
106
|
EOS
|
|
105
|
-
expect(src).to reek_of(:IrresponsibleModule)
|
|
107
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo')
|
|
106
108
|
end
|
|
107
109
|
|
|
108
110
|
it 'reports modules that have both nested modules and singleton methods' do
|
|
@@ -115,7 +117,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
115
117
|
end
|
|
116
118
|
end
|
|
117
119
|
EOS
|
|
118
|
-
expect(src).to reek_of(:IrresponsibleModule)
|
|
120
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo')
|
|
119
121
|
end
|
|
120
122
|
|
|
121
123
|
it 'reports modules that have both nested modules and methods on the singleton class' do
|
|
@@ -130,7 +132,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
130
132
|
end
|
|
131
133
|
end
|
|
132
134
|
EOS
|
|
133
|
-
expect(src).to reek_of(:IrresponsibleModule)
|
|
135
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo')
|
|
134
136
|
end
|
|
135
137
|
|
|
136
138
|
it 'does not report namespace modules that have a nested class through assignment' do
|
|
@@ -149,7 +151,7 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
149
151
|
src = <<-EOS
|
|
150
152
|
class Foo < Bar; end
|
|
151
153
|
EOS
|
|
152
|
-
expect(src).to reek_of(:IrresponsibleModule)
|
|
154
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo')
|
|
153
155
|
end
|
|
154
156
|
|
|
155
157
|
it 'reports classes defined through assignment' do
|
|
@@ -159,14 +161,14 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
159
161
|
Foo = Class.new Bar
|
|
160
162
|
end
|
|
161
163
|
EOS
|
|
162
|
-
expect(src).to reek_of(:IrresponsibleModule,
|
|
164
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Qux::Foo')
|
|
163
165
|
end
|
|
164
166
|
|
|
165
167
|
it 'reports top level classes defined through assignment' do
|
|
166
168
|
src = <<-EOS
|
|
167
169
|
Foo = Class.new Bar
|
|
168
170
|
EOS
|
|
169
|
-
expect(src).to reek_of(:IrresponsibleModule,
|
|
171
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo')
|
|
170
172
|
end
|
|
171
173
|
|
|
172
174
|
it 'reports structs defined through assignment' do
|
|
@@ -176,14 +178,14 @@ RSpec.describe Reek::Smells::IrresponsibleModule do
|
|
|
176
178
|
Foo = Struct.new(:x, :y)
|
|
177
179
|
end
|
|
178
180
|
EOS
|
|
179
|
-
expect(src).to reek_of(:IrresponsibleModule,
|
|
181
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Qux::Foo')
|
|
180
182
|
end
|
|
181
183
|
|
|
182
184
|
it 'reports top level structs defined through assignment' do
|
|
183
185
|
src = <<-EOS
|
|
184
186
|
Foo = Struct.new(:x, :y)
|
|
185
187
|
EOS
|
|
186
|
-
expect(src).to reek_of(:IrresponsibleModule,
|
|
188
|
+
expect(src).to reek_of(:IrresponsibleModule, context: 'Foo')
|
|
187
189
|
end
|
|
188
190
|
|
|
189
191
|
it 'does not report constants that are not classes' do
|
|
@@ -87,7 +87,7 @@ RSpec.describe Reek::Smells::LongParameterList do
|
|
|
87
87
|
end
|
|
88
88
|
EOS
|
|
89
89
|
ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
90
|
-
detector.
|
|
90
|
+
detector.sniff(ctx).first
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
it_should_behave_like 'common fields set correctly'
|
|
@@ -99,5 +99,9 @@ RSpec.describe Reek::Smells::LongParameterList do
|
|
|
99
99
|
it 'reports the line number of the method' do
|
|
100
100
|
expect(warning.lines).to eq([1])
|
|
101
101
|
end
|
|
102
|
+
|
|
103
|
+
it 'has the right message' do
|
|
104
|
+
expect(warning.message).to eq('has 4 parameters')
|
|
105
|
+
end
|
|
102
106
|
end
|
|
103
107
|
end
|
|
@@ -13,14 +13,17 @@ RSpec.describe Reek::Smells::LongYieldList do
|
|
|
13
13
|
src = 'def simple(arga, argb, &blk) f(3);yield; end'
|
|
14
14
|
expect(src).not_to reek_of(:LongYieldList)
|
|
15
15
|
end
|
|
16
|
+
|
|
16
17
|
it 'should not report yield with few parameters' do
|
|
17
18
|
src = 'def simple(arga, argb, &blk) f(3);yield a,b; end'
|
|
18
19
|
expect(src).not_to reek_of(:LongYieldList)
|
|
19
20
|
end
|
|
21
|
+
|
|
20
22
|
it 'should report yield with many parameters' do
|
|
21
23
|
src = 'def simple(arga, argb, &blk) f(3);yield arga,argb,arga,argb; end'
|
|
22
24
|
expect(src).to reek_of(:LongYieldList, count: 4)
|
|
23
25
|
end
|
|
26
|
+
|
|
24
27
|
it 'should not report yield of a long expression' do
|
|
25
28
|
src = 'def simple(arga, argb, &blk) f(3);yield(if @dec then argb else 5+3 end); end'
|
|
26
29
|
expect(src).not_to reek_of(:LongYieldList)
|
|
@@ -33,10 +36,10 @@ RSpec.describe Reek::Smells::LongYieldList do
|
|
|
33
36
|
def simple(arga, argb, &blk)
|
|
34
37
|
f(3)
|
|
35
38
|
yield(arga,argb,arga,argb)
|
|
36
|
-
|
|
39
|
+
end
|
|
37
40
|
EOS
|
|
38
41
|
ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
39
|
-
detector.
|
|
42
|
+
detector.sniff(ctx).first
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
it_should_behave_like 'common fields set correctly'
|
|
@@ -69,7 +69,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
69
69
|
) { |qux| qux.quuz }
|
|
70
70
|
end
|
|
71
71
|
EOS
|
|
72
|
-
expect(src).to reek_of(:NestedIterators,
|
|
72
|
+
expect(src).to reek_of(:NestedIterators, depth: 2)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
it 'reports the deepest level of nesting only' do
|
|
@@ -82,8 +82,8 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
82
82
|
}
|
|
83
83
|
end
|
|
84
84
|
EOS
|
|
85
|
-
expect(src).not_to reek_of(:NestedIterators,
|
|
86
|
-
expect(src).to reek_of(:NestedIterators,
|
|
85
|
+
expect(src).not_to reek_of(:NestedIterators, depth: 2)
|
|
86
|
+
expect(src).to reek_of(:NestedIterators, depth: 3)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
it 'handles the case where super receives a block' do
|
|
@@ -110,7 +110,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
110
110
|
expect(src).to reek_of(:NestedIterators)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
describe '
|
|
113
|
+
describe 'sniff / warnings' do
|
|
114
114
|
let(:detector) { build(:smell_detector, smell_type: :NestedIterators) }
|
|
115
115
|
|
|
116
116
|
it 'reports a sensible warning message' do
|
|
@@ -132,7 +132,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
132
132
|
end
|
|
133
133
|
end
|
|
134
134
|
EOS
|
|
135
|
-
expect(source).to reek_of(:NestedIterators,
|
|
135
|
+
expect(source).to reek_of(:NestedIterators, lines: [3])
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
it 'reports all lines on which nested iterators occur' do
|
|
@@ -143,7 +143,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
143
143
|
end
|
|
144
144
|
EOS
|
|
145
145
|
|
|
146
|
-
expect(source).to reek_of(:NestedIterators,
|
|
146
|
+
expect(source).to reek_of(:NestedIterators, lines: [2, 3])
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
it 'reports separete cases of nested iterators if levels are different' do
|
|
@@ -153,8 +153,8 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
153
153
|
@jim.each {|ting| ting.each {|piece| piece.each {|atom| atom.foo } } }
|
|
154
154
|
end
|
|
155
155
|
EOS
|
|
156
|
-
expect(source).to reek_of(:NestedIterators,
|
|
157
|
-
expect(source).to reek_of(:NestedIterators,
|
|
156
|
+
expect(source).to reek_of(:NestedIterators, lines: [2], depth: 2)
|
|
157
|
+
expect(source).to reek_of(:NestedIterators, lines: [3], depth: 3)
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
160
|
|
|
@@ -193,6 +193,30 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
193
193
|
end
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
+
it 'reports nested iterators called via safe navigation' do
|
|
197
|
+
source = <<-EOS
|
|
198
|
+
def show_bottles(bars)
|
|
199
|
+
bars&.each do |bar|
|
|
200
|
+
bar&.each do |bottle|
|
|
201
|
+
puts bottle
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
EOS
|
|
206
|
+
expect(source).to reek_of(:NestedIterators)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it 'does not report unnested iterators called via safe navigation' do
|
|
210
|
+
source = <<-EOS
|
|
211
|
+
def show_bottles(bar)
|
|
212
|
+
bar&.each do |bottle|
|
|
213
|
+
puts bottle
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
EOS
|
|
217
|
+
expect(source).not_to reek_of(:NestedIterators)
|
|
218
|
+
end
|
|
219
|
+
|
|
196
220
|
context 'when the allowed nesting depth is 3' do
|
|
197
221
|
let(:config) do
|
|
198
222
|
{ Reek::Smells::NestedIterators::MAX_ALLOWED_NESTING_KEY => 3 }
|
|
@@ -250,7 +274,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
250
274
|
@fred.ignore_me {|item| item.each {|ting| ting.each {|other| other.other} } }
|
|
251
275
|
end
|
|
252
276
|
'
|
|
253
|
-
expect(src).to reek_of(:NestedIterators,
|
|
277
|
+
expect(src).to reek_of(:NestedIterators, depth: 2).with_config(config)
|
|
254
278
|
end
|
|
255
279
|
|
|
256
280
|
it 'should report nested iterators outside the ignored iterator' do
|
|
@@ -259,7 +283,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
259
283
|
@fred.each {|item| item.each {|ting| ting.ignore_me {|other| other.other} } }
|
|
260
284
|
end
|
|
261
285
|
'
|
|
262
|
-
expect(src).to reek_of(:NestedIterators,
|
|
286
|
+
expect(src).to reek_of(:NestedIterators, depth: 2).with_config(config)
|
|
263
287
|
end
|
|
264
288
|
|
|
265
289
|
it 'should report nested iterators with the ignored iterator between them' do
|
|
@@ -268,7 +292,7 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
268
292
|
@fred.each {|item| item.ignore_me {|ting| ting.ting {|other| other.other} } }
|
|
269
293
|
end
|
|
270
294
|
'
|
|
271
|
-
expect(src).to reek_of(:NestedIterators,
|
|
295
|
+
expect(src).to reek_of(:NestedIterators, depth: 2).with_config(config)
|
|
272
296
|
end
|
|
273
297
|
end
|
|
274
298
|
end
|
|
@@ -288,13 +312,13 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
|
288
312
|
end
|
|
289
313
|
EOS
|
|
290
314
|
ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
291
|
-
detector.
|
|
315
|
+
detector.sniff(ctx).first
|
|
292
316
|
end
|
|
293
317
|
|
|
294
318
|
it_should_behave_like 'common fields set correctly'
|
|
295
319
|
|
|
296
320
|
it 'reports correct values' do
|
|
297
|
-
expect(warning.parameters[:
|
|
321
|
+
expect(warning.parameters[:depth]).to eq(2)
|
|
298
322
|
expect(warning.lines).to eq([3])
|
|
299
323
|
end
|
|
300
324
|
end
|
|
@@ -4,73 +4,70 @@ require_lib 'reek/smells/nil_check'
|
|
|
4
4
|
require_relative 'smell_detector_shared'
|
|
5
5
|
|
|
6
6
|
RSpec.describe Reek::Smells::NilCheck do
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
src = <<-EOS
|
|
7
|
+
it 'reports correctly the basic use case' do
|
|
8
|
+
src = <<-EOS
|
|
10
9
|
def nilcheck foo
|
|
11
10
|
foo.nil?
|
|
12
11
|
end
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
12
|
+
EOS
|
|
13
|
+
expect(src).to reek_of :NilCheck,
|
|
14
|
+
lines: [2],
|
|
15
|
+
message: 'performs a nil-check'
|
|
16
|
+
end
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
it 'reports nothing when scope includes no nil checks' do
|
|
19
|
+
expect('def no_nils; end').not_to reek_of(:NilCheck)
|
|
20
|
+
end
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
end
|
|
31
|
-
EOS
|
|
32
|
-
expect(src).to reek_of(:NilCheck)
|
|
22
|
+
it 'reports when scope uses multiple nil? methods' do
|
|
23
|
+
src = <<-EOS
|
|
24
|
+
def chk_multi_nil(para)
|
|
25
|
+
para.nil?
|
|
26
|
+
puts "Hello"
|
|
27
|
+
\"\".nil?
|
|
33
28
|
end
|
|
29
|
+
EOS
|
|
30
|
+
expect(src).to reek_of(:NilCheck)
|
|
31
|
+
end
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
end
|
|
41
|
-
EOS
|
|
42
|
-
expect(src).to reek_of(:NilCheck)
|
|
33
|
+
it 'reports twice when scope uses == nil and === nil' do
|
|
34
|
+
src = <<-EOS
|
|
35
|
+
def chk_eq_nil(para)
|
|
36
|
+
para == nil
|
|
37
|
+
para === nil
|
|
43
38
|
end
|
|
39
|
+
EOS
|
|
40
|
+
expect(src).to reek_of(:NilCheck)
|
|
41
|
+
end
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
it 'reports when scope uses nil ==' do
|
|
44
|
+
expect('def chk_eq_nil_rev(para); nil == para; end').to reek_of(:NilCheck)
|
|
45
|
+
end
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
end
|
|
47
|
+
it 'reports when scope uses multiple case-clauses checking nil' do
|
|
48
|
+
src = <<-EOS
|
|
49
|
+
def case_nil
|
|
50
|
+
case @inst_var
|
|
51
|
+
when nil then puts "Nil"
|
|
52
|
+
end
|
|
53
|
+
puts "Hello"
|
|
54
|
+
case @inst_var2
|
|
55
|
+
when 1 then puts 1
|
|
56
|
+
when nil then puts nil.inspect
|
|
60
57
|
end
|
|
61
|
-
EOS
|
|
62
|
-
expect(src).to reek_of(:NilCheck)
|
|
63
58
|
end
|
|
59
|
+
EOS
|
|
60
|
+
expect(src).to reek_of(:NilCheck)
|
|
61
|
+
end
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
end
|
|
63
|
+
it 'reports a when clause that checks nil and other values' do
|
|
64
|
+
src = <<-EOS
|
|
65
|
+
def case_nil
|
|
66
|
+
case @inst_var
|
|
67
|
+
when nil, false then puts "Hello"
|
|
71
68
|
end
|
|
72
|
-
EOS
|
|
73
|
-
expect(src).to reek_of(:NilCheck)
|
|
74
69
|
end
|
|
70
|
+
EOS
|
|
71
|
+
expect(src).to reek_of(:NilCheck)
|
|
75
72
|
end
|
|
76
73
|
end
|