reek 4.7.1 → 5.0.0
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/.codeclimate.yml +17 -12
- data/.rubocop.yml +36 -7
- data/.simplecov +1 -0
- data/.travis.yml +3 -9
- data/.yardopts +1 -1
- data/CHANGELOG.md +59 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +5 -5
- data/README.md +134 -104
- data/Rakefile +16 -3
- data/bin/reek +1 -3
- data/docs/API.md +2 -9
- data/docs/Basic-Smell-Options.md +51 -11
- data/docs/Code-Smells.md +1 -1
- data/docs/Command-Line-Options.md +14 -4
- data/docs/Duplicate-Method-Call.md +49 -1
- data/docs/Feature-Envy.md +44 -0
- data/docs/How-To-Write-New-Detectors.md +7 -7
- data/docs/Instance-Variable-Assumption.md +1 -1
- data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
- data/docs/Rake-Task.md +1 -1
- data/docs/Reek-4-to-Reek-5-migration.md +193 -0
- data/docs/Reek-Driven-Development.md +1 -1
- data/docs/Uncommunicative-Method-Name.md +45 -6
- data/docs/Uncommunicative-Module-Name.md +49 -7
- data/docs/Uncommunicative-Parameter-Name.md +43 -5
- data/docs/Uncommunicative-Variable-Name.md +73 -2
- data/docs/Unused-Private-Method.md +3 -3
- data/docs/defaults.reek.yml +129 -0
- data/docs/yard_plugin.rb +1 -0
- data/features/command_line_interface/basic_usage.feature +2 -2
- data/features/command_line_interface/options.feature +46 -4
- data/features/command_line_interface/show_progress.feature +4 -4
- data/features/command_line_interface/smell_selection.feature +1 -1
- data/features/command_line_interface/smells_count.feature +6 -6
- data/features/command_line_interface/stdin.feature +30 -8
- data/features/configuration_files/accept_setting.feature +45 -28
- data/features/configuration_files/directory_specific_directives.feature +80 -75
- data/features/configuration_files/exclude_directives.feature +11 -10
- data/features/configuration_files/exclude_paths_directives.feature +4 -4
- data/features/configuration_files/masking_smells.feature +38 -9
- data/features/configuration_files/mix_accept_reject_setting.feature +31 -28
- data/features/configuration_files/reject_setting.feature +52 -41
- data/features/configuration_files/schema_validation.feature +59 -0
- data/features/configuration_files/unused_private_method.feature +18 -16
- data/features/configuration_loading.feature +53 -10
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +3 -3
- data/features/configuration_via_source_comments/well_formed_source_comments.feature +2 -2
- data/features/locales.feature +32 -0
- data/features/rake_task/rake_task.feature +58 -18
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +34 -34
- data/features/reports/yaml.feature +3 -3
- data/features/rspec_matcher.feature +40 -0
- data/features/samples.feature +287 -287
- data/features/step_definitions/reek_steps.rb +2 -2
- data/features/step_definitions/sample_file_steps.rb +9 -4
- data/features/support/env.rb +2 -11
- data/features/todo_list.feature +26 -23
- data/lib/reek/ast/builder.rb +1 -1
- data/lib/reek/ast/node.rb +40 -58
- data/lib/reek/ast/object_refs.rb +1 -1
- data/lib/reek/ast/reference_collector.rb +2 -4
- data/lib/reek/ast/sexp_extensions/case.rb +1 -1
- data/lib/reek/ast/sexp_extensions/if.rb +8 -1
- data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
- data/lib/reek/ast/sexp_extensions/methods.rb +4 -6
- data/lib/reek/ast/sexp_extensions/send.rb +0 -4
- data/lib/reek/cli/application.rb +4 -3
- data/lib/reek/cli/command/report_command.rb +1 -2
- data/lib/reek/cli/command/todo_list_command.rb +8 -8
- data/lib/reek/cli/options.rb +31 -16
- data/lib/reek/cli/silencer.rb +14 -3
- data/lib/reek/code_comment.rb +14 -16
- data/lib/reek/configuration/app_configuration.rb +32 -27
- data/lib/reek/configuration/configuration_converter.rb +110 -0
- data/lib/reek/configuration/configuration_file_finder.rb +16 -41
- data/lib/reek/configuration/configuration_validator.rb +12 -23
- data/lib/reek/configuration/default_directive.rb +17 -3
- data/lib/reek/configuration/directory_directives.rb +17 -11
- data/lib/reek/configuration/excluded_paths.rb +1 -1
- data/lib/reek/configuration/rake_task_converter.rb +29 -0
- data/lib/reek/configuration/schema.yml +210 -0
- data/lib/reek/configuration/schema_validator.rb +38 -0
- data/lib/reek/context/attribute_context.rb +3 -3
- data/lib/reek/context/code_context.rb +47 -43
- data/lib/reek/context/ghost_context.rb +0 -2
- data/lib/reek/context/method_context.rb +22 -15
- data/lib/reek/context/module_context.rb +5 -9
- data/lib/reek/context/root_context.rb +0 -4
- data/lib/reek/context/send_context.rb +2 -2
- data/lib/reek/context_builder.rb +43 -44
- data/lib/reek/detector_repository.rb +11 -11
- data/lib/reek/documentation_link.rb +28 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +14 -13
- data/lib/reek/errors/bad_detector_in_comment_error.rb +12 -11
- data/lib/reek/errors/base_error.rb +3 -0
- data/lib/reek/errors/config_file_error.rb +11 -0
- data/lib/reek/errors/encoding_error.rb +43 -0
- data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +13 -12
- data/lib/reek/errors/incomprehensible_source_error.rb +22 -24
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +24 -26
- data/lib/reek/logging_error_handler.rb +7 -5
- data/lib/reek/rake/task.rb +8 -4
- data/lib/reek/report/base_report.rb +8 -12
- data/lib/reek/report/code_climate/code_climate_configuration.rb +1 -1
- data/lib/reek/report/code_climate/code_climate_configuration.yml +6 -10
- data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
- data/lib/reek/report/heading_formatter.rb +54 -0
- data/lib/reek/report/json_report.rb +1 -1
- data/lib/reek/report/location_formatter.rb +40 -0
- data/lib/reek/report/progress_formatter.rb +79 -0
- data/lib/reek/report/simple_warning_formatter.rb +34 -0
- data/lib/reek/report/text_report.rb +1 -2
- data/lib/reek/report/xml_report.rb +3 -3
- data/lib/reek/report/yaml_report.rb +1 -1
- data/lib/reek/report.rb +15 -10
- data/lib/reek/smell_configuration.rb +2 -2
- data/lib/reek/smell_detectors/attribute.rb +5 -11
- data/lib/reek/smell_detectors/base_detector.rb +30 -26
- data/lib/reek/smell_detectors/boolean_parameter.rb +3 -5
- data/lib/reek/smell_detectors/class_variable.rb +5 -14
- data/lib/reek/smell_detectors/control_parameter.rb +18 -33
- data/lib/reek/smell_detectors/data_clump.rb +15 -9
- data/lib/reek/smell_detectors/duplicate_method_call.rb +23 -17
- data/lib/reek/smell_detectors/feature_envy.rb +9 -7
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +14 -23
- data/lib/reek/smell_detectors/irresponsible_module.rb +5 -12
- data/lib/reek/smell_detectors/long_parameter_list.rb +10 -7
- data/lib/reek/smell_detectors/long_yield_list.rb +10 -7
- data/lib/reek/smell_detectors/manual_dispatch.rb +4 -5
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +20 -20
- data/lib/reek/smell_detectors/module_initialize.rb +3 -5
- data/lib/reek/smell_detectors/nested_iterators.rb +16 -24
- data/lib/reek/smell_detectors/nil_check.rb +8 -15
- data/lib/reek/smell_detectors/repeated_conditional.rb +13 -11
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +7 -8
- data/lib/reek/smell_detectors/too_many_constants.rb +10 -9
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +10 -6
- data/lib/reek/smell_detectors/too_many_methods.rb +11 -7
- data/lib/reek/smell_detectors/too_many_statements.rb +10 -6
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +10 -11
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +14 -18
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +17 -22
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +26 -27
- data/lib/reek/smell_detectors/unused_parameters.rb +4 -6
- data/lib/reek/smell_detectors/unused_private_method.rb +11 -18
- data/lib/reek/smell_detectors/utility_function.rb +12 -16
- data/lib/reek/smell_detectors.rb +1 -2
- data/lib/reek/smell_warning.rb +15 -8
- data/lib/reek/source/source_code.rb +57 -58
- data/lib/reek/source/source_locator.rb +8 -8
- data/lib/reek/spec/should_reek.rb +2 -2
- data/lib/reek/spec/should_reek_of.rb +9 -16
- data/lib/reek/spec/should_reek_only_of.rb +4 -4
- data/lib/reek/spec.rb +6 -6
- data/lib/reek/tree_dresser.rb +8 -8
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +5 -7
- data/samples/checkstyle.xml +1 -1
- data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
- data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
- data/samples/configuration/full_configuration.reek +8 -4
- data/samples/configuration/full_mask.reek +5 -4
- data/samples/configuration/partial_mask.reek +3 -2
- data/samples/configuration/regular_configuration/.reek.yml +4 -0
- data/samples/paths.rb +5 -4
- data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
- data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
- data/spec/factories/factories.rb +2 -13
- data/spec/reek/ast/node_spec.rb +103 -10
- data/spec/reek/ast/reference_collector_spec.rb +1 -1
- data/spec/reek/ast/sexp_extensions_spec.rb +14 -34
- data/spec/reek/cli/application_spec.rb +52 -42
- data/spec/reek/cli/command/todo_list_command_spec.rb +6 -4
- data/spec/reek/cli/silencer_spec.rb +28 -0
- data/spec/reek/code_comment_spec.rb +31 -38
- data/spec/reek/configuration/app_configuration_spec.rb +46 -33
- data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -51
- data/spec/reek/configuration/default_directive_spec.rb +1 -1
- data/spec/reek/configuration/directory_directives_spec.rb +6 -7
- data/spec/reek/configuration/excluded_paths_spec.rb +6 -6
- data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
- data/spec/reek/configuration/schema_validator_spec.rb +165 -0
- data/spec/reek/context/code_context_spec.rb +70 -106
- data/spec/reek/context/ghost_context_spec.rb +9 -9
- data/spec/reek/context/method_context_spec.rb +2 -2
- data/spec/reek/context/module_context_spec.rb +3 -3
- data/spec/reek/context/root_context_spec.rb +1 -1
- data/spec/reek/context_builder_spec.rb +20 -0
- data/spec/reek/documentation_link_spec.rb +20 -0
- data/spec/reek/errors/base_error_spec.rb +13 -0
- data/spec/reek/examiner_spec.rb +136 -29
- data/spec/reek/rake/task_spec.rb +25 -2
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -80
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/json_report_spec.rb +13 -46
- data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
- data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
- data/spec/reek/report/text_report_spec.rb +4 -4
- data/spec/reek/report/xml_report_spec.rb +3 -3
- data/spec/reek/report/yaml_report_spec.rb +9 -38
- data/spec/reek/report_spec.rb +3 -3
- data/spec/reek/smell_detectors/base_detector_spec.rb +4 -5
- data/spec/reek/smell_detectors/boolean_parameter_spec.rb +2 -2
- data/spec/reek/smell_detectors/class_variable_spec.rb +26 -32
- data/spec/reek/smell_detectors/control_parameter_spec.rb +34 -4
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +3 -3
- data/spec/reek/smell_detectors/feature_envy_spec.rb +47 -2
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -11
- data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +10 -10
- data/spec/reek/smell_detectors/module_initialize_spec.rb +14 -0
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +1 -1
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +36 -15
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +9 -9
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +3 -3
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +21 -10
- data/spec/reek/smell_detectors/utility_function_spec.rb +57 -5
- data/spec/reek/smell_warning_spec.rb +12 -8
- data/spec/reek/source/source_code_spec.rb +22 -21
- data/spec/reek/source/source_locator_spec.rb +17 -17
- data/spec/reek/spec/should_reek_of_spec.rb +25 -29
- data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
- data/spec/reek/spec/should_reek_spec.rb +8 -8
- data/spec/reek/spec/smell_matcher_spec.rb +23 -23
- data/spec/reek/tree_dresser_spec.rb +12 -17
- data/spec/spec_helper.rb +6 -17
- data/tasks/configuration.rake +8 -5
- metadata +74 -41
- data/defaults.reek +0 -131
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
- data/lib/reek/report/formatter/heading_formatter.rb +0 -52
- data/lib/reek/report/formatter/location_formatter.rb +0 -42
- data/lib/reek/report/formatter/progress_formatter.rb +0 -81
- data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -36
- data/lib/reek/report/formatter.rb +0 -33
- data/lib/reek/smell_detectors/syntax.rb +0 -37
- data/samples/configuration/non_public_modifiers_mask.reek +0 -3
- data/samples/smelly_with_inline_mask.rb +0 -8
- data/samples/smelly_with_modifiers.rb +0 -12
- data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
- data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
- data/spec/reek/smell_detectors/syntax_spec.rb +0 -17
- /data/{samples/configuration/more_than_one_configuration_file/regular.reek → .reek.yml} +0 -0
- /data/samples/{clean.rb → clean_source/clean.rb} +0 -0
- /data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
- /data/samples/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
- /data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +0 -0
- /data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
- /data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
- /data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
- /data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
- /data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
|
@@ -98,7 +98,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
98
98
|
expect(src).to reek_of(:UtilityFunction, context: 'simple')
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
context '
|
|
101
|
+
context 'when examining singleton methods' do
|
|
102
102
|
['class', 'module'].each do |scope|
|
|
103
103
|
it "does not report for #{scope} with `class << self` notation" do
|
|
104
104
|
src = "#{scope} Alfa; class << self; def bravo(charlie) charlie.to_s; end; end; end"
|
|
@@ -111,7 +111,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
context 'by using `module_function`' do
|
|
114
|
+
context 'when defined by using `module_function`' do
|
|
115
115
|
it 'does not report UtilityFunction also when using multiple arguments' do
|
|
116
116
|
src = <<-EOS
|
|
117
117
|
class Alfa
|
|
@@ -194,7 +194,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
194
194
|
{ Reek::SmellDetectors::UtilityFunction::PUBLIC_METHODS_ONLY_KEY => true }
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
context 'public methods' do
|
|
197
|
+
context 'when examining public methods' do
|
|
198
198
|
it 'still reports UtilityFunction' do
|
|
199
199
|
src = <<-EOS
|
|
200
200
|
class Alfa
|
|
@@ -208,7 +208,7 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
208
208
|
end
|
|
209
209
|
end
|
|
210
210
|
|
|
211
|
-
context 'private methods' do
|
|
211
|
+
context 'when examining private methods' do
|
|
212
212
|
it 'does not report UtilityFunction' do
|
|
213
213
|
src = <<-EOS
|
|
214
214
|
class Alfa
|
|
@@ -221,9 +221,21 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
221
221
|
|
|
222
222
|
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
|
223
223
|
end
|
|
224
|
+
|
|
225
|
+
it 'does not report UtilityFunction when private is used as a def modifier' do
|
|
226
|
+
src = <<-EOS
|
|
227
|
+
class Alfa
|
|
228
|
+
private def bravo(charlie)
|
|
229
|
+
charlie.delta.echo
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
EOS
|
|
233
|
+
|
|
234
|
+
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
|
235
|
+
end
|
|
224
236
|
end
|
|
225
237
|
|
|
226
|
-
context 'protected methods' do
|
|
238
|
+
context 'when examining protected methods' do
|
|
227
239
|
it 'does not report UtilityFunction' do
|
|
228
240
|
src = <<-EOS
|
|
229
241
|
class Alfa
|
|
@@ -236,6 +248,46 @@ RSpec.describe Reek::SmellDetectors::UtilityFunction do
|
|
|
236
248
|
|
|
237
249
|
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
|
238
250
|
end
|
|
251
|
+
|
|
252
|
+
it 'does not report UtilityFunction when protected is used as a def modifier' do
|
|
253
|
+
src = <<-EOS
|
|
254
|
+
class Alfa
|
|
255
|
+
protected def bravo(charlie)
|
|
256
|
+
charlie.delta.echo
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
EOS
|
|
260
|
+
|
|
261
|
+
expect(src).not_to reek_of(:UtilityFunction).with_config(config)
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
describe 'disabling with a comment' do
|
|
267
|
+
it 'disables the method following the comment' do
|
|
268
|
+
src = <<-EOS
|
|
269
|
+
class Alfa
|
|
270
|
+
# :reek:UtilityFunction
|
|
271
|
+
def bravo(charlie)
|
|
272
|
+
charlie.delta.echo
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
EOS
|
|
276
|
+
|
|
277
|
+
expect(src).not_to reek_of(:UtilityFunction)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
it 'disables a method when it has a visibility modifier' do
|
|
281
|
+
src = <<-EOS
|
|
282
|
+
class Alfa
|
|
283
|
+
# :reek:UtilityFunction
|
|
284
|
+
private def bravo(charlie)
|
|
285
|
+
charlie.delta.echo
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
EOS
|
|
289
|
+
|
|
290
|
+
expect(src).not_to reek_of(:UtilityFunction)
|
|
239
291
|
end
|
|
240
292
|
end
|
|
241
293
|
end
|
|
@@ -7,7 +7,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
7
7
|
let(:utility_function_detector) { build(:smell_detector, smell_type: 'UtilityFunction') }
|
|
8
8
|
let(:uncommunicative_name_detector) { build(:smell_detector, smell_type: 'UncommunicativeVariableName') }
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
describe 'sort order' do
|
|
11
11
|
shared_examples_for 'first sorts ahead of second' do
|
|
12
12
|
it 'hash differently' do
|
|
13
13
|
expect(first.hash).not_to eq(second.hash)
|
|
@@ -26,21 +26,21 @@ RSpec.describe Reek::SmellWarning do
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
context 'smells
|
|
29
|
+
context 'when smells differ only by detector' do
|
|
30
30
|
let(:first) { build(:smell_warning, smell_detector: duplication_detector) }
|
|
31
31
|
let(:second) { build(:smell_warning, smell_detector: feature_envy_detector) }
|
|
32
32
|
|
|
33
33
|
it_behaves_like 'first sorts ahead of second'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
context 'smells
|
|
36
|
+
context 'when smells differ only by lines' do
|
|
37
37
|
let(:first) { build(:smell_warning, smell_detector: feature_envy_detector, lines: [2]) }
|
|
38
38
|
let(:second) { build(:smell_warning, smell_detector: feature_envy_detector, lines: [3]) }
|
|
39
39
|
|
|
40
40
|
it_behaves_like 'first sorts ahead of second'
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
context 'smells
|
|
43
|
+
context 'when smells differ only by context' do
|
|
44
44
|
let(:first) { build(:smell_warning, smell_detector: duplication_detector, context: 'first') }
|
|
45
45
|
let(:second) do
|
|
46
46
|
build(:smell_warning, smell_detector: duplication_detector, context: 'second')
|
|
@@ -49,7 +49,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
49
49
|
it_behaves_like 'first sorts ahead of second'
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
context 'smells
|
|
52
|
+
context 'when smells differ only by message' do
|
|
53
53
|
let(:first) do
|
|
54
54
|
build(:smell_warning, smell_detector: duplication_detector,
|
|
55
55
|
context: 'ctx', message: 'first message')
|
|
@@ -62,7 +62,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
62
62
|
it_behaves_like 'first sorts ahead of second'
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
context '
|
|
65
|
+
context 'when smells differ by name and message' do
|
|
66
66
|
let(:first) do
|
|
67
67
|
build(:smell_warning, smell_detector: feature_envy_detector, message: 'second message')
|
|
68
68
|
end
|
|
@@ -73,7 +73,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
73
73
|
it_behaves_like 'first sorts ahead of second'
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
-
context 'smells
|
|
76
|
+
context 'when smells differ everywhere' do
|
|
77
77
|
let(:first) do
|
|
78
78
|
build(:smell_warning, smell_detector: duplication_detector,
|
|
79
79
|
context: 'Dirty#a',
|
|
@@ -97,7 +97,7 @@ RSpec.describe Reek::SmellWarning do
|
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
describe '#yaml_hash' do
|
|
101
101
|
let(:context_name) { 'Module::Class#method/block' }
|
|
102
102
|
let(:lines) { [24, 513] }
|
|
103
103
|
let(:message) { 'test message' }
|
|
@@ -135,6 +135,10 @@ RSpec.describe Reek::SmellWarning do
|
|
|
135
135
|
expect(yaml['source']).to eq source
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
it 'includes the documentation link' do
|
|
139
|
+
expect(yaml['documentation_link']).to eq Reek::DocumentationLink.build('FeatureEnvy')
|
|
140
|
+
end
|
|
141
|
+
|
|
138
142
|
it 'includes the parameters' do
|
|
139
143
|
parameters.each do |key, value|
|
|
140
144
|
expect(yaml[key]).to eq value
|
|
@@ -6,59 +6,60 @@ 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 = described_class.new(
|
|
9
|
+
source_code = described_class.new(source: 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 = described_class.new(
|
|
15
|
+
source_code = described_class.new(source: '', origin: '(string)')
|
|
16
16
|
result = source_code.syntax_tree
|
|
17
|
-
expect(result).to
|
|
17
|
+
expect(result.type).to eq :empty
|
|
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 = described_class.new(
|
|
22
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
23
23
|
result = source_code.syntax_tree
|
|
24
|
-
expect(result).to
|
|
24
|
+
expect(result.type).to eq :empty
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it 'does not crash with sequences incompatible with UTF-8' do
|
|
28
28
|
source = '"\xFF"'
|
|
29
|
-
source_code = described_class.new(
|
|
29
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
30
30
|
result = source_code.syntax_tree
|
|
31
31
|
expect(result.children.first).to eq "\xFF"
|
|
32
32
|
end
|
|
33
|
-
end
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
it 'returns a :lambda node for lambda expressions' do
|
|
35
|
+
source = '->() { }'
|
|
36
|
+
source_code = described_class.new(source: source, origin: '(string)')
|
|
37
|
+
result = source_code.syntax_tree
|
|
38
|
+
expect(result.children.first.type).to eq :lambda
|
|
39
|
+
end
|
|
38
40
|
|
|
39
|
-
context 'with a Parser::SyntaxError' do
|
|
41
|
+
context 'when the parser fails with a Parser::SyntaxError' do
|
|
42
|
+
let(:src) { described_class.new(source: code) }
|
|
40
43
|
let(:code) { '== Invalid Syntax ==' }
|
|
41
|
-
let(:parser) { {} }
|
|
42
44
|
|
|
43
|
-
it '
|
|
44
|
-
expect
|
|
45
|
+
it 'raises the error' do
|
|
46
|
+
expect { src.syntax_tree }.to raise_error Parser::SyntaxError
|
|
45
47
|
end
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
context 'with a generic error' do
|
|
50
|
+
context 'when the parser fails with a generic error' do
|
|
49
51
|
let(:code) { '' }
|
|
52
|
+
let(:parser) { instance_double('Parser::Ruby25') }
|
|
53
|
+
let(:src) { described_class.new(source: code, parser: parser) }
|
|
50
54
|
let(:error_class) { RuntimeError }
|
|
51
55
|
let(:error_message) { 'An error' }
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
|
|
57
|
+
before do
|
|
54
58
|
allow(parser).to receive(:parse_with_comments).and_raise(error_class, error_message)
|
|
55
|
-
{
|
|
56
|
-
parser: parser
|
|
57
|
-
}
|
|
58
59
|
end
|
|
59
60
|
|
|
60
61
|
it 'raises the error' do
|
|
61
|
-
expect { src }.to raise_error error_class, error_message
|
|
62
|
+
expect { src.syntax_tree }.to raise_error error_class, error_message
|
|
62
63
|
end
|
|
63
64
|
end
|
|
64
65
|
end
|
|
@@ -5,15 +5,15 @@ require_lib 'reek/source/source_locator'
|
|
|
5
5
|
|
|
6
6
|
RSpec.describe Reek::Source::SourceLocator do
|
|
7
7
|
describe '#sources' do
|
|
8
|
-
context 'applied to hidden directories' do
|
|
9
|
-
let(:path) {
|
|
8
|
+
context 'when applied to hidden directories' do
|
|
9
|
+
let(:path) { SAMPLES_DIR.join('source_with_hidden_directories') }
|
|
10
10
|
|
|
11
11
|
let(:expected_paths) do
|
|
12
|
-
[path.join('
|
|
12
|
+
[path.join('not_hidden.rb')]
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
let(:paths_that_are_expected_to_be_ignored) do
|
|
16
|
-
[path.join('.hidden/
|
|
16
|
+
[path.join('.hidden/hidden.rb')]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
it 'does not scan hidden directories' do
|
|
@@ -30,21 +30,21 @@ RSpec.describe Reek::Source::SourceLocator do
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# rubocop:disable RSpec/NestedGroups
|
|
33
|
-
context '
|
|
33
|
+
context 'with excluded paths' do
|
|
34
34
|
let(:configuration) do
|
|
35
|
-
test_configuration_for(
|
|
35
|
+
test_configuration_for(CONFIGURATION_DIR.join('with_excluded_paths.reek'))
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
let(:options) { instance_double('Reek::CLI::Options', force_exclusion?: false) }
|
|
39
39
|
|
|
40
40
|
context 'when the path is absolute' do
|
|
41
41
|
let(:path) do
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
SAMPLES_DIR.join('source_with_exclude_paths',
|
|
43
|
+
'ignore_me',
|
|
44
|
+
'uncommunicative_method_name.rb').expand_path
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
context '
|
|
47
|
+
context 'when options.force_exclusion? is true' do
|
|
48
48
|
before do
|
|
49
49
|
allow(options).to receive(:force_exclusion?).and_return(true)
|
|
50
50
|
end
|
|
@@ -55,7 +55,7 @@ RSpec.describe Reek::Source::SourceLocator do
|
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
context '
|
|
58
|
+
context 'when options.force_exclusion? is false' do
|
|
59
59
|
before do
|
|
60
60
|
allow(options).to receive(:force_exclusion?).and_return(false)
|
|
61
61
|
end
|
|
@@ -68,7 +68,7 @@ RSpec.describe Reek::Source::SourceLocator do
|
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
context 'when the path is a file name in an excluded directory' do
|
|
71
|
-
let(:path) {
|
|
71
|
+
let(:path) { SAMPLES_DIR.join('source_with_exclude_paths', 'ignore_me', 'uncommunicative_method_name.rb') }
|
|
72
72
|
|
|
73
73
|
context 'when options.force_exclusion? is true' do
|
|
74
74
|
before do
|
|
@@ -94,7 +94,7 @@ RSpec.describe Reek::Source::SourceLocator do
|
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
context 'when path is a directory' do
|
|
97
|
-
let(:path) {
|
|
97
|
+
let(:path) { SAMPLES_DIR.join('source_with_exclude_paths') }
|
|
98
98
|
|
|
99
99
|
let(:expected_paths) do
|
|
100
100
|
[path.join('nested/uncommunicative_parameter_name.rb')]
|
|
@@ -120,10 +120,10 @@ RSpec.describe Reek::Source::SourceLocator do
|
|
|
120
120
|
end
|
|
121
121
|
# rubocop:enable RSpec/NestedGroups
|
|
122
122
|
|
|
123
|
-
context 'non-Ruby paths' do
|
|
124
|
-
let(:path) {
|
|
123
|
+
context 'with non-Ruby paths' do
|
|
124
|
+
let(:path) { SAMPLES_DIR.join('source_with_non_ruby_files') }
|
|
125
125
|
let(:expected_sources) do
|
|
126
|
-
[path.join('
|
|
126
|
+
[path.join('ruby.rb')]
|
|
127
127
|
end
|
|
128
128
|
let(:paths_that_are_expected_to_be_ignored) do
|
|
129
129
|
[
|
|
@@ -145,7 +145,7 @@ RSpec.describe Reek::Source::SourceLocator do
|
|
|
145
145
|
end
|
|
146
146
|
end
|
|
147
147
|
|
|
148
|
-
context 'passing "." or "./" as argument' do
|
|
148
|
+
context 'when passing "." or "./" as argument' do
|
|
149
149
|
let(:expected_sources) do
|
|
150
150
|
[Pathname.new('spec/spec_helper.rb'), Pathname.new('lib/reek.rb')]
|
|
151
151
|
end
|
|
@@ -11,50 +11,46 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
11
11
|
expect(ruby).to reek_of(:DuplicateMethodCall)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
it 'reports duplicate calls by smell detector class' do
|
|
15
|
-
expect(ruby).to reek_of(Reek::SmellDetectors::DuplicateMethodCall)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
14
|
it 'does not report any feature envy' do
|
|
19
15
|
expect(ruby).not_to reek_of(:FeatureEnvy)
|
|
20
16
|
end
|
|
21
17
|
end
|
|
22
18
|
|
|
23
19
|
describe 'different sources of input' do
|
|
24
|
-
context 'checking code in a string' do
|
|
20
|
+
context 'when checking code in a string' do
|
|
25
21
|
let(:clean_code) { 'def good() true; end' }
|
|
26
22
|
let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
|
|
27
23
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
28
24
|
|
|
29
25
|
it 'matches a smelly String' do
|
|
30
|
-
expect(matcher.
|
|
26
|
+
expect(matcher).to be_matches(smelly_code)
|
|
31
27
|
end
|
|
32
28
|
|
|
33
29
|
it 'doesnt match a fragrant String' do
|
|
34
|
-
expect(matcher.
|
|
30
|
+
expect(matcher).not_to be_matches(clean_code)
|
|
35
31
|
end
|
|
36
32
|
|
|
37
33
|
it 're-calculates matches every time' do
|
|
38
34
|
matcher.matches? smelly_code
|
|
39
|
-
expect(matcher.
|
|
35
|
+
expect(matcher).not_to be_matches(clean_code)
|
|
40
36
|
end
|
|
41
37
|
end
|
|
42
38
|
|
|
43
|
-
context 'checking code in a File' do
|
|
39
|
+
context 'when checking code in a File' do
|
|
44
40
|
let(:matcher) { described_class.new(:UncommunicativeMethodName, name: 'x') }
|
|
45
41
|
|
|
46
42
|
it 'matches a smelly file' do
|
|
47
|
-
expect(matcher.
|
|
43
|
+
expect(matcher).to be_matches(SMELLY_FILE)
|
|
48
44
|
end
|
|
49
45
|
|
|
50
46
|
it 'doesnt match a fragrant file' do
|
|
51
|
-
expect(matcher.
|
|
47
|
+
expect(matcher).not_to be_matches(CLEAN_FILE)
|
|
52
48
|
end
|
|
53
49
|
end
|
|
54
50
|
end
|
|
55
51
|
|
|
56
52
|
describe 'smell types and smell details' do
|
|
57
|
-
context 'passing in smell_details with unknown parameter name' do
|
|
53
|
+
context 'when passing in smell_details with unknown parameter name' do
|
|
58
54
|
let(:matcher) { described_class.new(:UncommunicativeVariableName, foo: 'y') }
|
|
59
55
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
60
56
|
|
|
@@ -63,23 +59,23 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
63
59
|
end
|
|
64
60
|
end
|
|
65
61
|
|
|
66
|
-
context 'both are matching' do
|
|
62
|
+
context 'when both are matching' do
|
|
67
63
|
let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
|
|
68
64
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
69
65
|
|
|
70
66
|
it 'is truthy' do
|
|
71
|
-
expect(matcher.
|
|
67
|
+
expect(matcher).to be_matches(smelly_code)
|
|
72
68
|
end
|
|
73
69
|
end
|
|
74
70
|
|
|
75
|
-
context 'no smell_type is matching' do
|
|
71
|
+
context 'when no smell_type is matching' do
|
|
76
72
|
let(:smelly_code) { 'def dummy() y = 4; end' }
|
|
77
73
|
|
|
78
74
|
let(:falsey_matcher) { described_class.new(:FeatureEnvy, name: 'y') }
|
|
79
75
|
let(:truthy_matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
|
|
80
76
|
|
|
81
77
|
it 'is falsey' do
|
|
82
|
-
expect(falsey_matcher.
|
|
78
|
+
expect(falsey_matcher).not_to be_matches(smelly_code)
|
|
83
79
|
end
|
|
84
80
|
|
|
85
81
|
it 'sets the proper error message' do
|
|
@@ -97,12 +93,12 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
97
93
|
end
|
|
98
94
|
end
|
|
99
95
|
|
|
100
|
-
context 'smell type is matching but smell details are not' do
|
|
96
|
+
context 'when smell type is matching but smell details are not' do
|
|
101
97
|
let(:smelly_code) { 'def double_thing() @other.thing.foo + @other.thing.foo end' }
|
|
102
98
|
let(:matcher) { described_class.new(:DuplicateMethodCall, name: 'foo', count: 15) }
|
|
103
99
|
|
|
104
100
|
it 'is falsey' do
|
|
105
|
-
expect(matcher.
|
|
101
|
+
expect(matcher).not_to be_matches(smelly_code)
|
|
106
102
|
end
|
|
107
103
|
|
|
108
104
|
it 'sets the proper error message' do
|
|
@@ -129,15 +125,15 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
129
125
|
end
|
|
130
126
|
end
|
|
131
127
|
|
|
132
|
-
context '
|
|
133
|
-
before do
|
|
134
|
-
default_config = Reek::SmellDetectors::UnusedPrivateMethod.default_config
|
|
135
|
-
expect(default_config[Reek::SmellConfiguration::ENABLED_KEY]).to be_falsy
|
|
136
|
-
end
|
|
137
|
-
|
|
128
|
+
context 'with a smell that is disabled by default' do
|
|
138
129
|
it 'enables the smell detector to match automatically' do
|
|
130
|
+
default_config = Reek::SmellDetectors::UnusedPrivateMethod.default_config
|
|
139
131
|
src = 'class C; private; def foo; end; end'
|
|
140
|
-
|
|
132
|
+
|
|
133
|
+
aggregate_failures do
|
|
134
|
+
expect(default_config[Reek::SmellConfiguration::ENABLED_KEY]).to be_falsy
|
|
135
|
+
expect(src).to reek_of(:UnusedPrivateMethod)
|
|
136
|
+
end
|
|
141
137
|
end
|
|
142
138
|
end
|
|
143
139
|
|
|
@@ -146,13 +142,13 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
146
142
|
let(:configured_matcher) { matcher.with_config('accept' => 'x') }
|
|
147
143
|
|
|
148
144
|
it 'uses the passed-in configuration for matching' do
|
|
149
|
-
expect(configured_matcher.
|
|
150
|
-
expect(configured_matcher.
|
|
145
|
+
expect(configured_matcher).to be_matches('def foo; q = 2; end')
|
|
146
|
+
expect(configured_matcher).not_to be_matches('def foo; x = 2; end')
|
|
151
147
|
end
|
|
152
148
|
|
|
153
149
|
it 'leaves the original matcher intact' do
|
|
154
|
-
expect(configured_matcher.
|
|
155
|
-
expect(matcher.
|
|
150
|
+
expect(configured_matcher).not_to be_matches('def foo; x = 2; end')
|
|
151
|
+
expect(matcher).to be_matches('def foo; x = 2; end')
|
|
156
152
|
end
|
|
157
153
|
end
|
|
158
154
|
end
|
|
@@ -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 { allow(examiner).to receive(:
|
|
24
|
+
before { allow(examiner).to receive(:origin).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
|
-
allow(examiner).to receive(:
|
|
94
|
+
allow(examiner).to receive(:origin).and_return(source)
|
|
95
95
|
expect(matcher.failure_message_when_negated).to match(source)
|
|
96
96
|
end
|
|
97
97
|
end
|
|
@@ -8,11 +8,11 @@ RSpec.describe Reek::Spec::ShouldReek do
|
|
|
8
8
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
9
9
|
|
|
10
10
|
it 'matches a smelly String' do
|
|
11
|
-
expect(matcher.
|
|
11
|
+
expect(matcher).to be_matches(smelly_code)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it 'doesnt match a fragrant String' do
|
|
15
|
-
expect(matcher.
|
|
15
|
+
expect(matcher).not_to be_matches(clean_code)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it 'reports the smells when should_not fails' do
|
|
@@ -22,15 +22,15 @@ RSpec.describe Reek::Spec::ShouldReek do
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
describe 'checking code in a File' do
|
|
25
|
-
context '
|
|
25
|
+
context 'without masking' do
|
|
26
26
|
let(:matcher) { described_class.new }
|
|
27
27
|
|
|
28
28
|
it 'matches a smelly File' do
|
|
29
|
-
expect(matcher.
|
|
29
|
+
expect(matcher).to be_matches(SMELLY_FILE)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it 'doesnt match a fragrant File' do
|
|
33
|
-
expect(matcher.
|
|
33
|
+
expect(matcher).not_to be_matches(CLEAN_FILE)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
it 'reports the smells when should_not fails' do
|
|
@@ -39,13 +39,13 @@ RSpec.describe Reek::Spec::ShouldReek do
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
context '
|
|
43
|
-
let(:path) {
|
|
42
|
+
context 'with masking' do
|
|
43
|
+
let(:path) { CONFIGURATION_DIR.join('full_mask.reek') }
|
|
44
44
|
let(:configuration) { test_configuration_for(path) }
|
|
45
45
|
let(:matcher) { described_class.new(configuration: configuration) }
|
|
46
46
|
|
|
47
47
|
it 'masks smells using the relevant configuration' do
|
|
48
|
-
expect(matcher.
|
|
48
|
+
expect(matcher).not_to be_matches(SMELLY_FILE)
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -10,35 +10,35 @@ RSpec.describe Reek::Spec::SmellMatcher do
|
|
|
10
10
|
end
|
|
11
11
|
let(:matcher) { described_class.new(smell_warning) }
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
describe '#matches?' do
|
|
14
14
|
it 'matches on class symbol' do
|
|
15
|
-
expect(matcher.
|
|
15
|
+
expect(matcher).to be_matches(:UncommunicativeVariableName)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it 'matches on class symbol and params' do
|
|
19
|
-
expect(matcher.
|
|
20
|
-
|
|
19
|
+
expect(matcher).to be_matches(:UncommunicativeVariableName,
|
|
20
|
+
test: 'something')
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it 'matches on class symbol, params and attributes' do
|
|
24
|
-
expect(matcher.
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
expect(matcher).to be_matches(:UncommunicativeVariableName,
|
|
25
|
+
test: 'something',
|
|
26
|
+
message: "has the variable name '@s'")
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it 'does not match on different class symbol' do
|
|
30
|
-
expect(matcher.
|
|
30
|
+
expect(matcher).not_to be_matches(:FeatureEnvy)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it 'does not match on different params' do
|
|
34
|
-
expect(matcher.
|
|
35
|
-
|
|
34
|
+
expect(matcher).not_to be_matches(:UncommunicativeVariableName,
|
|
35
|
+
test: 'something else')
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
it 'does not match on different attributes' do
|
|
39
|
-
expect(matcher.
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
expect(matcher).not_to be_matches(:UncommunicativeVariableName,
|
|
40
|
+
test: 'something',
|
|
41
|
+
message: 'nothing')
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it 'raises error on uncomparable attribute' do
|
|
@@ -50,33 +50,33 @@ RSpec.describe Reek::Spec::SmellMatcher do
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
describe '#matches_smell_type?' do
|
|
54
54
|
it 'matches on class symbol' do
|
|
55
|
-
expect(matcher.
|
|
55
|
+
expect(matcher).to be_matches_smell_type(:UncommunicativeVariableName)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
it 'does not match on different class symbol' do
|
|
59
|
-
expect(matcher.
|
|
59
|
+
expect(matcher).not_to be_matches_smell_type(:FeatureEnvy)
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
describe '#matches_attributes?' do
|
|
64
64
|
it 'matches on params' do
|
|
65
|
-
expect(matcher.
|
|
65
|
+
expect(matcher).to be_matches_attributes(test: 'something')
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it 'matches on class symbol, params and attributes' do
|
|
69
|
-
expect(matcher.
|
|
70
|
-
|
|
69
|
+
expect(matcher).to be_matches_attributes(test: 'something',
|
|
70
|
+
message: "has the variable name '@s'")
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
it 'does not match on different params' do
|
|
74
|
-
expect(matcher.
|
|
74
|
+
expect(matcher).not_to be_matches_attributes(test: 'something else')
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
it 'does not match on different attributes' do
|
|
78
|
-
expect(matcher.
|
|
79
|
-
|
|
78
|
+
expect(matcher).not_to be_matches_attributes(test: 'something',
|
|
79
|
+
message: 'nothing')
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it 'raises error on uncomparable attribute' do
|