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
data/spec/reek/examiner_spec.rb
CHANGED
|
@@ -43,23 +43,46 @@ RSpec.describe Reek::Examiner do
|
|
|
43
43
|
context 'with a partially masked smelly File' do
|
|
44
44
|
let(:configuration) { test_configuration_for(path) }
|
|
45
45
|
let(:examiner) do
|
|
46
|
-
described_class.new(
|
|
46
|
+
described_class.new(SMELLY_FILE,
|
|
47
47
|
filter_by_smells: [],
|
|
48
48
|
configuration: configuration)
|
|
49
49
|
end
|
|
50
|
-
let(:path) {
|
|
51
|
-
let(:
|
|
50
|
+
let(:path) { CONFIG_PATH.join('partial_mask.reek') }
|
|
51
|
+
let(:expected_first_smell) { 'UncommunicativeVariableName' }
|
|
52
52
|
|
|
53
53
|
it_should_behave_like 'one smell found'
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
context 'with a fragrant File' do
|
|
57
|
-
let(:
|
|
58
|
-
let(:examiner) { described_class.new(clean_file) }
|
|
57
|
+
let(:examiner) { described_class.new(CLEAN_FILE) }
|
|
59
58
|
|
|
60
59
|
it_should_behave_like 'no smells found'
|
|
61
60
|
end
|
|
62
61
|
|
|
62
|
+
describe '.new' do
|
|
63
|
+
context 'returns a proper Examiner' do
|
|
64
|
+
let(:source) { 'class C; def f; end; end' }
|
|
65
|
+
let(:examiner) do
|
|
66
|
+
described_class.new(source)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'has been run on the given source' do
|
|
70
|
+
expect(examiner.description).to eq('string')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'has the right smells' do
|
|
74
|
+
smells = examiner.smells
|
|
75
|
+
expect(smells[0].message).to eq('has no descriptive comment')
|
|
76
|
+
expect(smells[1].message).to eq("has the name 'f'")
|
|
77
|
+
expect(smells[2].message).to eq("has the name 'C'")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'has the right smell count' do
|
|
81
|
+
expect(examiner.smells_count).to eq(3)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
63
86
|
describe '#smells' do
|
|
64
87
|
it 'returns the detected smell warnings' do
|
|
65
88
|
code = 'def foo; bar.call_me(); bar.call_me(); end'
|
|
@@ -69,5 +92,61 @@ RSpec.describe Reek::Examiner do
|
|
|
69
92
|
expect(smell).to be_a(Reek::Smells::SmellWarning)
|
|
70
93
|
expect(smell.message).to eq('calls bar.call_me() 2 times')
|
|
71
94
|
end
|
|
95
|
+
|
|
96
|
+
context 'source is empty' do
|
|
97
|
+
let(:source) do
|
|
98
|
+
<<-EOS
|
|
99
|
+
# Just a comment
|
|
100
|
+
# And another
|
|
101
|
+
EOS
|
|
102
|
+
end
|
|
103
|
+
let(:examiner) do
|
|
104
|
+
described_class.new(source)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'has no warnings' do
|
|
108
|
+
expect(examiner.smells).to eq([])
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context 'with an incomprehensible source that causes Reek to crash' do
|
|
113
|
+
let(:source) { 'class C; def does_crash_reek; end; end' }
|
|
114
|
+
|
|
115
|
+
subject do
|
|
116
|
+
smell_repository = instance_double 'Reek::Smells::SmellRepository'
|
|
117
|
+
expect(smell_repository).to receive(:examine) do
|
|
118
|
+
raise ArgumentError, 'Looks like bad source'
|
|
119
|
+
end
|
|
120
|
+
class_double('Reek::Smells::SmellRepository').as_stubbed_const
|
|
121
|
+
allow(Reek::Smells::SmellRepository).to receive(:eligible_smell_types)
|
|
122
|
+
expect(Reek::Smells::SmellRepository).to receive(:new) { smell_repository }
|
|
123
|
+
|
|
124
|
+
examiner = described_class.new source
|
|
125
|
+
examiner
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it 'has no warnings' do
|
|
129
|
+
Reek::CLI::Silencer.silently do
|
|
130
|
+
expect(subject.smells).to be_empty
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
describe 'message on STDERR' do
|
|
135
|
+
it 'contains the origin' do
|
|
136
|
+
origin = 'string'
|
|
137
|
+
expect { subject.smells }.to output(/#{origin}/).to_stderr
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it 'explains what to do' do
|
|
141
|
+
explanation = 'It would be great if you could report this back to the Reek team'
|
|
142
|
+
expect { subject.smells }.to output(/#{explanation}/).to_stderr
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'contains the original exception' do
|
|
146
|
+
original = '#<ArgumentError: Looks like bad source>'
|
|
147
|
+
expect { subject.smells }.to output(/#{original}/).to_stderr
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
72
151
|
end
|
|
73
152
|
end
|
|
@@ -46,8 +46,7 @@ RSpec.describe Reek::Report::JSONReport do
|
|
|
46
46
|
"lines": [1],
|
|
47
47
|
"message": "doesn't depend on instance state (maybe move it to another class?)",
|
|
48
48
|
"smell_type": "UtilityFunction",
|
|
49
|
-
"source": "string"
|
|
50
|
-
"name": "simple"
|
|
49
|
+
"source": "string"
|
|
51
50
|
}
|
|
52
51
|
]
|
|
53
52
|
EOS
|
|
@@ -80,7 +79,6 @@ RSpec.describe Reek::Report::JSONReport do
|
|
|
80
79
|
"message": "doesn't depend on instance state (maybe move it to another class?)",
|
|
81
80
|
"smell_type": "UtilityFunction",
|
|
82
81
|
"source": "string",
|
|
83
|
-
"name": "simple",
|
|
84
82
|
"wiki_link": "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
|
|
85
83
|
}
|
|
86
84
|
]
|
|
@@ -15,10 +15,9 @@ RSpec.describe Reek::Report::XMLReport do
|
|
|
15
15
|
|
|
16
16
|
context 'source with voliations' do
|
|
17
17
|
it 'prints non-empty checkstyle XML' do
|
|
18
|
-
|
|
19
|
-
xml_report.add_examiner Reek::Examiner.new(path)
|
|
18
|
+
xml_report.add_examiner Reek::Examiner.new(SMELLY_FILE)
|
|
20
19
|
xml = SAMPLES_PATH.join('checkstyle.xml').read
|
|
21
|
-
xml = xml.gsub(
|
|
20
|
+
xml = xml.gsub(SMELLY_FILE.to_s, SMELLY_FILE.expand_path.to_s)
|
|
22
21
|
expect { xml_report.show }.to output(xml).to_stdout
|
|
23
22
|
end
|
|
24
23
|
end
|
|
@@ -46,7 +46,6 @@ RSpec.describe Reek::Report::YAMLReport do
|
|
|
46
46
|
message: "doesn't depend on instance state (maybe move it to another class?)"
|
|
47
47
|
smell_type: "UtilityFunction"
|
|
48
48
|
source: "string"
|
|
49
|
-
name: "simple"
|
|
50
49
|
EOS
|
|
51
50
|
|
|
52
51
|
expect(result).to eq expected
|
|
@@ -75,7 +74,6 @@ RSpec.describe Reek::Report::YAMLReport do
|
|
|
75
74
|
message: "doesn't depend on instance state (maybe move it to another class?)"
|
|
76
75
|
smell_type: "UtilityFunction"
|
|
77
76
|
source: "string"
|
|
78
|
-
name: "simple"
|
|
79
77
|
wiki_link: "https://github.com/troessner/reek/blob/master/docs/Utility-Function.md"
|
|
80
78
|
EOS
|
|
81
79
|
|
|
@@ -7,6 +7,17 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
7
7
|
|
|
8
8
|
it_should_behave_like 'SmellDetector'
|
|
9
9
|
|
|
10
|
+
it 'reports the right values' do
|
|
11
|
+
src = <<-EOS
|
|
12
|
+
class Klass
|
|
13
|
+
attr_writer :my_attr
|
|
14
|
+
end
|
|
15
|
+
EOS
|
|
16
|
+
expect(src).to reek_of(:Attribute,
|
|
17
|
+
lines: [2],
|
|
18
|
+
message: 'is a writable attribute')
|
|
19
|
+
end
|
|
20
|
+
|
|
10
21
|
context 'with no attributes' do
|
|
11
22
|
it 'records nothing' do
|
|
12
23
|
src = <<-EOS
|
|
@@ -34,7 +45,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
34
45
|
attr_writer :my_attr
|
|
35
46
|
end
|
|
36
47
|
EOS
|
|
37
|
-
expect(src).to reek_of(:Attribute,
|
|
48
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
38
49
|
end
|
|
39
50
|
|
|
40
51
|
it 'does not record writer attribute if suppressed with a preceding code comment' do
|
|
@@ -53,7 +64,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
53
64
|
attr_writer :my_attr
|
|
54
65
|
end
|
|
55
66
|
EOS
|
|
56
|
-
expect(src).to reek_of(:Attribute,
|
|
67
|
+
expect(src).to reek_of(:Attribute, context: 'Mod#my_attr')
|
|
57
68
|
end
|
|
58
69
|
|
|
59
70
|
it 'records accessor attribute' do
|
|
@@ -62,7 +73,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
62
73
|
attr_accessor :my_attr
|
|
63
74
|
end
|
|
64
75
|
EOS
|
|
65
|
-
expect(src).to reek_of(:Attribute,
|
|
76
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
66
77
|
end
|
|
67
78
|
|
|
68
79
|
it 'records attr defining a writer' do
|
|
@@ -71,7 +82,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
71
82
|
attr :my_attr, true
|
|
72
83
|
end
|
|
73
84
|
EOS
|
|
74
|
-
expect(src).to reek_of(:Attribute,
|
|
85
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
75
86
|
end
|
|
76
87
|
|
|
77
88
|
it "doesn't record protected attributes" do
|
|
@@ -110,7 +121,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
110
121
|
attr_writer :my_attr
|
|
111
122
|
end
|
|
112
123
|
EOS
|
|
113
|
-
expect(src).to reek_of(:Attribute,
|
|
124
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
114
125
|
end
|
|
115
126
|
|
|
116
127
|
it 'records attr_writer after switching visbility to public' do
|
|
@@ -121,7 +132,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
121
132
|
public :my_attr
|
|
122
133
|
end
|
|
123
134
|
EOS
|
|
124
|
-
expect(src).to reek_of(:Attribute,
|
|
135
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
125
136
|
end
|
|
126
137
|
|
|
127
138
|
it 'resets visibility in new contexts' do
|
|
@@ -135,7 +146,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
135
146
|
attr_writer :attr1
|
|
136
147
|
end
|
|
137
148
|
'
|
|
138
|
-
expect(src).to reek_of(:Attribute)
|
|
149
|
+
expect(src).to reek_of(:Attribute, context: 'OtherKlass#attr1')
|
|
139
150
|
end
|
|
140
151
|
|
|
141
152
|
it 'records attr_writer defining a class attribute' do
|
|
@@ -146,7 +157,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
146
157
|
end
|
|
147
158
|
end
|
|
148
159
|
EOS
|
|
149
|
-
expect(src).to reek_of(:Attribute,
|
|
160
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
150
161
|
end
|
|
151
162
|
|
|
152
163
|
it 'does not record private class attributes' do
|
|
@@ -158,7 +169,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
158
169
|
end
|
|
159
170
|
end
|
|
160
171
|
EOS
|
|
161
|
-
expect(src).not_to reek_of(:Attribute
|
|
172
|
+
expect(src).not_to reek_of(:Attribute)
|
|
162
173
|
end
|
|
163
174
|
|
|
164
175
|
it 'tracks visibility in metaclasses separately' do
|
|
@@ -170,7 +181,7 @@ RSpec.describe Reek::Smells::Attribute do
|
|
|
170
181
|
end
|
|
171
182
|
end
|
|
172
183
|
EOS
|
|
173
|
-
expect(src).to reek_of(:Attribute,
|
|
184
|
+
expect(src).to reek_of(:Attribute, context: 'Klass#my_attr')
|
|
174
185
|
end
|
|
175
186
|
end
|
|
176
187
|
end
|
|
@@ -7,24 +7,24 @@ RSpec.describe Reek::Smells::BooleanParameter do
|
|
|
7
7
|
context 'in a method' do
|
|
8
8
|
it 'reports a parameter defaulted to true' do
|
|
9
9
|
src = 'def cc(arga = true); arga; end'
|
|
10
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
10
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
it 'reports a parameter defaulted to false' do
|
|
14
14
|
src = 'def cc(arga = false) end'
|
|
15
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
15
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it 'reports two parameters defaulted to booleans' do
|
|
19
19
|
src = 'def cc(nowt, arga = true, argb = false, &blk) end'
|
|
20
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
21
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
20
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
21
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'argb')
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'reports keyword parameters defaulted to booleans' do
|
|
25
25
|
src = 'def cc(arga: true, argb: false) end'
|
|
26
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
27
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
26
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
27
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'argb')
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it 'does not report regular parameters' do
|
|
@@ -51,18 +51,18 @@ RSpec.describe Reek::Smells::BooleanParameter do
|
|
|
51
51
|
context 'in a singleton method' do
|
|
52
52
|
it 'reports a parameter defaulted to true' do
|
|
53
53
|
src = 'def self.cc(arga = true) end'
|
|
54
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
54
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
it 'reports a parameter defaulted to false' do
|
|
58
58
|
src = 'def fred.cc(arga = false) end'
|
|
59
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
59
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
it 'reports two parameters defaulted to booleans' do
|
|
63
63
|
src = 'def Module.cc(nowt, arga = true, argb = false, &blk) end'
|
|
64
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
65
|
-
expect(src).to reek_of(:BooleanParameter,
|
|
64
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'arga')
|
|
65
|
+
expect(src).to reek_of(:BooleanParameter, parameter: 'argb')
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -76,14 +76,15 @@ RSpec.describe Reek::Smells::BooleanParameter do
|
|
|
76
76
|
let(:warning) do
|
|
77
77
|
src = 'def cc(arga = true) end'
|
|
78
78
|
ctx = Reek::Context::MethodContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
79
|
-
detector.
|
|
79
|
+
detector.sniff(ctx).first
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it_should_behave_like 'common fields set correctly'
|
|
83
83
|
|
|
84
84
|
it 'reports the correct values' do
|
|
85
|
-
expect(warning.parameters[:
|
|
85
|
+
expect(warning.parameters[:parameter]).to eq('arga')
|
|
86
86
|
expect(warning.lines).to eq([1])
|
|
87
|
+
expect(warning.message).to eq("has boolean parameter 'arga'")
|
|
87
88
|
end
|
|
88
89
|
end
|
|
89
90
|
end
|
|
@@ -12,19 +12,19 @@ RSpec.describe Reek::Smells::ClassVariable do
|
|
|
12
12
|
context 'with no class variables' do
|
|
13
13
|
it 'records nothing in the class' do
|
|
14
14
|
exp = sexp(:class, :Fred)
|
|
15
|
-
expect(detector.
|
|
15
|
+
expect(detector.sniff(Reek::Context::CodeContext.new(nil, exp))).to be_empty
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it 'records nothing in the module' do
|
|
19
19
|
exp = sexp(:module, :Fred)
|
|
20
|
-
expect(detector.
|
|
20
|
+
expect(detector.sniff(Reek::Context::CodeContext.new(nil, exp))).to be_empty
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
context 'with one class variable' do
|
|
25
25
|
shared_examples_for 'one variable found' do
|
|
26
26
|
let(:ast) { Reek::Source::SourceCode.from(src).syntax_tree }
|
|
27
|
-
let(:smells) { detector.
|
|
27
|
+
let(:smells) { detector.sniff(Reek::Context::CodeContext.new(nil, ast)) }
|
|
28
28
|
|
|
29
29
|
it 'records only that class variable' do
|
|
30
30
|
expect(smells.length).to eq(1)
|
|
@@ -85,7 +85,7 @@ RSpec.describe Reek::Smells::ClassVariable do
|
|
|
85
85
|
end
|
|
86
86
|
EOS
|
|
87
87
|
ctx = Reek::Context::CodeContext.new(nil, Reek::Source::SourceCode.from(src).syntax_tree)
|
|
88
|
-
detector.
|
|
88
|
+
detector.sniff(ctx).first
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
it_should_behave_like 'common fields set correctly'
|
|
@@ -32,72 +32,72 @@ RSpec.describe Reek::Smells::ControlParameter do
|
|
|
32
32
|
context 'parameter only used to determine code path' do
|
|
33
33
|
it 'reports a ternary check on a parameter' do
|
|
34
34
|
src = 'def simple(arga) arga ? @ivar : 3 end'
|
|
35
|
-
expect(src).to reek_of(:ControlParameter,
|
|
35
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arga')
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
it 'reports a couple inside a block' do
|
|
39
39
|
src = 'def blocks(arg) @text.map { |blk| arg ? blk : "#{blk}" } end'
|
|
40
|
-
expect(src).to reek_of(:ControlParameter,
|
|
40
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it 'reports on an if statement modifier' do
|
|
44
44
|
src = 'def simple(arg) args = {}; args.merge(\'a\' => \'A\') if arg end'
|
|
45
|
-
expect(src).to reek_of(:ControlParameter,
|
|
45
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it 'reports on an unless statement modifier' do
|
|
49
49
|
src = 'def simple(arg) args = {}; args.merge(\'a\' => \'A\') unless arg end'
|
|
50
|
-
expect(src).to reek_of(:ControlParameter,
|
|
50
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'reports on if control expression' do
|
|
54
54
|
src = 'def simple(arg) args = {}; if arg then args.merge(\'a\' => \'A\') end end'
|
|
55
|
-
expect(src).to reek_of(:ControlParameter,
|
|
55
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it 'reports on if control expression with &&' do
|
|
59
59
|
src = 'def simple(arg) if arg && true then puts "arg" end end'
|
|
60
|
-
expect(src).to reek_of(:ControlParameter,
|
|
60
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it 'reports on if control expression with preceding &&' do
|
|
64
64
|
src = 'def simple(arg) if true && arg then puts "arg" end end'
|
|
65
|
-
expect(src).to reek_of(:ControlParameter,
|
|
65
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it 'reports on if control expression with two && conditions' do
|
|
69
69
|
src = 'def simple(a) ag = {}; if a && true && true then puts "2" end end'
|
|
70
|
-
expect(src).to reek_of(:ControlParameter,
|
|
70
|
+
expect(src).to reek_of(:ControlParameter, argument: 'a')
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
it 'reports on if control expression with ||' do
|
|
74
74
|
src = 'def simple(arg) args = {}; if arg || true then puts "arg" end end'
|
|
75
|
-
expect(src).to reek_of(:ControlParameter,
|
|
75
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
it 'reports on if control expression with or' do
|
|
79
79
|
src = 'def simple(arg) args = {}; if arg or true then puts "arg" end end'
|
|
80
|
-
expect(src).to reek_of(:ControlParameter,
|
|
80
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
it 'reports on if control expression with if' do
|
|
84
84
|
src = 'def simple(arg) args = {}; if (arg if true) then puts "arg" end end'
|
|
85
|
-
expect(src).to reek_of(:ControlParameter,
|
|
85
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
it 'reports on && notation' do
|
|
89
89
|
src = 'def simple(arg) args = {}; arg && args.merge(\'a\' => \'A\') end'
|
|
90
|
-
expect(src).to reek_of(:ControlParameter,
|
|
90
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
it 'reports on || notation' do
|
|
94
94
|
src = 'def simple(arg) args = {}; arg || args.merge(\'a\' => \'A\') end'
|
|
95
|
-
expect(src).to reek_of(:ControlParameter,
|
|
95
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
it 'reports on case statement' do
|
|
99
99
|
src = 'def simple(arg) case arg when nil; nil when false; nil else nil end end'
|
|
100
|
-
expect(src).to reek_of(:ControlParameter,
|
|
100
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
it 'reports on nested if statements that are both control parameters' do
|
|
@@ -109,7 +109,7 @@ RSpec.describe Reek::Smells::ControlParameter do
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
EOS
|
|
112
|
-
expect(src).to reek_of(:ControlParameter,
|
|
112
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
it 'reports on nested if statements where the inner if is a control parameter' do
|
|
@@ -121,7 +121,7 @@ RSpec.describe Reek::Smells::ControlParameter do
|
|
|
121
121
|
end
|
|
122
122
|
end
|
|
123
123
|
EOS
|
|
124
|
-
expect(src).to reek_of(:ControlParameter,
|
|
124
|
+
expect(src).to reek_of(:ControlParameter, argument: 'arg')
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
it 'reports on explicit comparison in the condition' do
|
|
@@ -277,9 +277,16 @@ RSpec.describe Reek::Smells::ControlParameter do
|
|
|
277
277
|
|
|
278
278
|
it_should_behave_like 'common fields set correctly'
|
|
279
279
|
|
|
280
|
-
it '
|
|
281
|
-
expect(warning.parameters[:
|
|
280
|
+
it 'reports the argument' do
|
|
281
|
+
expect(warning.parameters[:argument]).to eq('arg')
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
it 'reports the lines' do
|
|
282
285
|
expect(warning.lines).to eq([3, 5])
|
|
283
286
|
end
|
|
287
|
+
|
|
288
|
+
it 'has the right message' do
|
|
289
|
+
expect(warning.message).to eq('is controlled by argument arg')
|
|
290
|
+
end
|
|
284
291
|
end
|
|
285
292
|
end
|