reek 4.6.0 → 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 +79 -26
- data/.simplecov +1 -0
- data/.travis.yml +3 -9
- data/.yardopts +1 -1
- data/CHANGELOG.md +76 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +5 -5
- data/README.md +138 -107
- data/Rakefile +16 -3
- data/bin/code_climate_reek +1 -0
- data/bin/reek +2 -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 +31 -5
- 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/codeclimate.feature +59 -0
- 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 +14 -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/ast_node_class_map.rb +1 -0
- data/lib/reek/ast/builder.rb +16 -0
- data/lib/reek/ast/node.rb +50 -58
- data/lib/reek/ast/object_refs.rb +2 -1
- data/lib/reek/ast/reference_collector.rb +3 -4
- data/lib/reek/ast/sexp_extensions/arguments.rb +1 -0
- data/lib/reek/ast/sexp_extensions/attribute_assignments.rb +1 -0
- data/lib/reek/ast/sexp_extensions/begin.rb +17 -0
- data/lib/reek/ast/sexp_extensions/block.rb +1 -0
- data/lib/reek/ast/sexp_extensions/case.rb +2 -1
- data/lib/reek/ast/sexp_extensions/constant.rb +1 -0
- data/lib/reek/ast/sexp_extensions/if.rb +9 -1
- data/lib/reek/ast/sexp_extensions/lambda.rb +1 -0
- data/lib/reek/ast/sexp_extensions/literal.rb +1 -0
- data/lib/reek/ast/sexp_extensions/logical_operators.rb +2 -1
- data/lib/reek/ast/sexp_extensions/methods.rb +5 -6
- data/lib/reek/ast/sexp_extensions/module.rb +55 -8
- data/lib/reek/ast/sexp_extensions/nested_assignables.rb +1 -0
- data/lib/reek/ast/sexp_extensions/self.rb +1 -0
- data/lib/reek/ast/sexp_extensions/send.rb +1 -4
- data/lib/reek/ast/sexp_extensions/super.rb +1 -0
- data/lib/reek/ast/sexp_extensions/symbols.rb +1 -0
- data/lib/reek/ast/sexp_extensions/variables.rb +1 -0
- data/lib/reek/ast/sexp_extensions/when.rb +1 -0
- data/lib/reek/ast/sexp_extensions/yield.rb +1 -0
- data/lib/reek/ast/sexp_extensions.rb +2 -0
- data/lib/reek/cli/application.rb +5 -3
- data/lib/reek/cli/command/base_command.rb +1 -0
- data/lib/reek/cli/command/report_command.rb +2 -2
- data/lib/reek/cli/command/todo_list_command.rb +9 -8
- data/lib/reek/cli/options.rb +32 -16
- data/lib/reek/cli/silencer.rb +15 -3
- data/lib/reek/cli/status.rb +1 -0
- data/lib/reek/code_comment.rb +14 -16
- data/lib/reek/configuration/app_configuration.rb +34 -28
- data/lib/reek/configuration/configuration_converter.rb +110 -0
- data/lib/reek/configuration/configuration_file_finder.rb +17 -41
- data/lib/reek/configuration/configuration_validator.rb +13 -23
- data/lib/reek/configuration/default_directive.rb +18 -3
- data/lib/reek/configuration/directory_directives.rb +18 -11
- data/lib/reek/configuration/excluded_paths.rb +2 -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 +4 -3
- data/lib/reek/context/class_context.rb +1 -0
- data/lib/reek/context/code_context.rb +49 -44
- data/lib/reek/context/ghost_context.rb +1 -2
- data/lib/reek/context/method_context.rb +26 -18
- data/lib/reek/context/module_context.rb +11 -11
- data/lib/reek/context/root_context.rb +1 -4
- data/lib/reek/context/send_context.rb +3 -2
- data/lib/reek/context/singleton_attribute_context.rb +1 -0
- data/lib/reek/context/singleton_method_context.rb +1 -0
- data/lib/reek/context/statement_counter.rb +1 -0
- data/lib/reek/context/visibility_tracker.rb +1 -0
- data/lib/reek/context_builder.rb +44 -44
- data/lib/reek/detector_repository.rb +12 -11
- data/lib/reek/documentation_link.rb +28 -0
- data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +15 -13
- data/lib/reek/errors/bad_detector_in_comment_error.rb +13 -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 +14 -12
- data/lib/reek/errors/incomprehensible_source_error.rb +23 -24
- data/lib/reek/errors/syntax_error.rb +41 -0
- data/lib/reek/examiner.rb +24 -22
- data/lib/reek/logging_error_handler.rb +8 -5
- data/lib/reek/rake/task.rb +8 -5
- data/lib/reek/report/base_report.rb +9 -12
- data/lib/reek/report/code_climate/code_climate_configuration.rb +2 -1
- data/lib/reek/report/code_climate/code_climate_configuration.yml +6 -6
- data/lib/reek/report/code_climate/code_climate_fingerprint.rb +1 -0
- data/lib/reek/report/code_climate/code_climate_formatter.rb +1 -0
- data/lib/reek/report/code_climate/code_climate_report.rb +1 -0
- data/lib/reek/report/code_climate.rb +1 -0
- data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
- data/lib/reek/report/heading_formatter.rb +54 -0
- data/lib/reek/report/html_report.rb +1 -0
- data/lib/reek/report/json_report.rb +2 -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 +2 -2
- data/lib/reek/report/xml_report.rb +4 -3
- data/lib/reek/report/yaml_report.rb +2 -1
- data/lib/reek/report.rb +16 -10
- data/lib/reek/smell_configuration.rb +3 -2
- data/lib/reek/smell_detectors/attribute.rb +6 -11
- data/lib/reek/smell_detectors/base_detector.rb +31 -26
- data/lib/reek/smell_detectors/boolean_parameter.rb +4 -5
- data/lib/reek/smell_detectors/class_variable.rb +6 -14
- data/lib/reek/smell_detectors/control_parameter.rb +19 -33
- data/lib/reek/smell_detectors/data_clump.rb +16 -9
- data/lib/reek/smell_detectors/duplicate_method_call.rb +24 -17
- data/lib/reek/smell_detectors/feature_envy.rb +10 -7
- data/lib/reek/smell_detectors/instance_variable_assumption.rb +15 -23
- data/lib/reek/smell_detectors/irresponsible_module.rb +6 -12
- data/lib/reek/smell_detectors/long_parameter_list.rb +11 -7
- data/lib/reek/smell_detectors/long_yield_list.rb +11 -7
- data/lib/reek/smell_detectors/manual_dispatch.rb +5 -5
- data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +21 -20
- data/lib/reek/smell_detectors/module_initialize.rb +4 -5
- data/lib/reek/smell_detectors/nested_iterators.rb +17 -24
- data/lib/reek/smell_detectors/nil_check.rb +9 -15
- data/lib/reek/smell_detectors/repeated_conditional.rb +14 -11
- data/lib/reek/smell_detectors/subclassed_from_core_class.rb +8 -8
- data/lib/reek/smell_detectors/too_many_constants.rb +11 -9
- data/lib/reek/smell_detectors/too_many_instance_variables.rb +11 -6
- data/lib/reek/smell_detectors/too_many_methods.rb +12 -7
- data/lib/reek/smell_detectors/too_many_statements.rb +11 -6
- data/lib/reek/smell_detectors/uncommunicative_method_name.rb +11 -11
- data/lib/reek/smell_detectors/uncommunicative_module_name.rb +15 -18
- data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +18 -22
- data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +27 -27
- data/lib/reek/smell_detectors/unused_parameters.rb +5 -6
- data/lib/reek/smell_detectors/unused_private_method.rb +14 -20
- data/lib/reek/smell_detectors/utility_function.rb +13 -16
- data/lib/reek/smell_detectors.rb +2 -1
- data/lib/reek/smell_warning.rb +16 -8
- data/lib/reek/source/source_code.rb +65 -46
- data/lib/reek/source/source_locator.rb +9 -8
- data/lib/reek/spec/should_reek.rb +3 -2
- data/lib/reek/spec/should_reek_of.rb +13 -26
- data/lib/reek/spec/should_reek_only_of.rb +5 -4
- data/lib/reek/spec/smell_matcher.rb +2 -1
- data/lib/reek/spec.rb +7 -6
- data/lib/reek/tree_dresser.rb +9 -8
- data/lib/reek/version.rb +2 -1
- data/lib/reek.rb +1 -0
- data/reek.gemspec +5 -6
- 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 +15 -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/statement_counter_spec.rb +1 -0
- 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 +137 -29
- data/spec/reek/rake/task_spec.rb +25 -2
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +82 -78
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +6 -6
- data/spec/reek/report/code_climate/code_climate_report_spec.rb +22 -22
- 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 +17 -46
- 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 +59 -21
- 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 +27 -38
- data/spec/reek/source/source_locator_spec.rb +42 -12
- data/spec/reek/spec/should_reek_of_spec.rb +25 -30
- 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 +7 -17
- data/tasks/configuration.rake +8 -5
- metadata +77 -40
- data/defaults.reek +0 -128
- data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
- data/lib/reek/errors/parse_error.rb +0 -19
- data/lib/reek/report/formatter/heading_formatter.rb +0 -51
- data/lib/reek/report/formatter/location_formatter.rb +0 -41
- data/lib/reek/report/formatter/progress_formatter.rb +0 -80
- data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -35
- data/lib/reek/report/formatter.rb +0 -32
- 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/{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
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require 'pathname'
|
|
2
2
|
require_relative '../../spec_helper'
|
|
3
3
|
require_lib 'reek/spec'
|
|
4
|
-
require 'active_support/core_ext/string/strip'
|
|
5
4
|
require 'active_support/core_ext/hash/except'
|
|
6
5
|
|
|
7
6
|
RSpec.describe Reek::Spec::ShouldReekOf do
|
|
@@ -12,50 +11,46 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
12
11
|
expect(ruby).to reek_of(:DuplicateMethodCall)
|
|
13
12
|
end
|
|
14
13
|
|
|
15
|
-
it 'reports duplicate calls by smell detector class' do
|
|
16
|
-
expect(ruby).to reek_of(Reek::SmellDetectors::DuplicateMethodCall)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
14
|
it 'does not report any feature envy' do
|
|
20
15
|
expect(ruby).not_to reek_of(:FeatureEnvy)
|
|
21
16
|
end
|
|
22
17
|
end
|
|
23
18
|
|
|
24
19
|
describe 'different sources of input' do
|
|
25
|
-
context 'checking code in a string' do
|
|
20
|
+
context 'when checking code in a string' do
|
|
26
21
|
let(:clean_code) { 'def good() true; end' }
|
|
27
22
|
let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
|
|
28
23
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
29
24
|
|
|
30
25
|
it 'matches a smelly String' do
|
|
31
|
-
expect(matcher.
|
|
26
|
+
expect(matcher).to be_matches(smelly_code)
|
|
32
27
|
end
|
|
33
28
|
|
|
34
29
|
it 'doesnt match a fragrant String' do
|
|
35
|
-
expect(matcher.
|
|
30
|
+
expect(matcher).not_to be_matches(clean_code)
|
|
36
31
|
end
|
|
37
32
|
|
|
38
33
|
it 're-calculates matches every time' do
|
|
39
34
|
matcher.matches? smelly_code
|
|
40
|
-
expect(matcher.
|
|
35
|
+
expect(matcher).not_to be_matches(clean_code)
|
|
41
36
|
end
|
|
42
37
|
end
|
|
43
38
|
|
|
44
|
-
context 'checking code in a File' do
|
|
39
|
+
context 'when checking code in a File' do
|
|
45
40
|
let(:matcher) { described_class.new(:UncommunicativeMethodName, name: 'x') }
|
|
46
41
|
|
|
47
42
|
it 'matches a smelly file' do
|
|
48
|
-
expect(matcher.
|
|
43
|
+
expect(matcher).to be_matches(SMELLY_FILE)
|
|
49
44
|
end
|
|
50
45
|
|
|
51
46
|
it 'doesnt match a fragrant file' do
|
|
52
|
-
expect(matcher.
|
|
47
|
+
expect(matcher).not_to be_matches(CLEAN_FILE)
|
|
53
48
|
end
|
|
54
49
|
end
|
|
55
50
|
end
|
|
56
51
|
|
|
57
52
|
describe 'smell types and smell details' do
|
|
58
|
-
context 'passing in smell_details with unknown parameter name' do
|
|
53
|
+
context 'when passing in smell_details with unknown parameter name' do
|
|
59
54
|
let(:matcher) { described_class.new(:UncommunicativeVariableName, foo: 'y') }
|
|
60
55
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
61
56
|
|
|
@@ -64,23 +59,23 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
64
59
|
end
|
|
65
60
|
end
|
|
66
61
|
|
|
67
|
-
context 'both are matching' do
|
|
62
|
+
context 'when both are matching' do
|
|
68
63
|
let(:matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
|
|
69
64
|
let(:smelly_code) { 'def x() y = 4; end' }
|
|
70
65
|
|
|
71
66
|
it 'is truthy' do
|
|
72
|
-
expect(matcher.
|
|
67
|
+
expect(matcher).to be_matches(smelly_code)
|
|
73
68
|
end
|
|
74
69
|
end
|
|
75
70
|
|
|
76
|
-
context 'no smell_type is matching' do
|
|
71
|
+
context 'when no smell_type is matching' do
|
|
77
72
|
let(:smelly_code) { 'def dummy() y = 4; end' }
|
|
78
73
|
|
|
79
74
|
let(:falsey_matcher) { described_class.new(:FeatureEnvy, name: 'y') }
|
|
80
75
|
let(:truthy_matcher) { described_class.new(:UncommunicativeVariableName, name: 'y') }
|
|
81
76
|
|
|
82
77
|
it 'is falsey' do
|
|
83
|
-
expect(falsey_matcher.
|
|
78
|
+
expect(falsey_matcher).not_to be_matches(smelly_code)
|
|
84
79
|
end
|
|
85
80
|
|
|
86
81
|
it 'sets the proper error message' do
|
|
@@ -98,12 +93,12 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
98
93
|
end
|
|
99
94
|
end
|
|
100
95
|
|
|
101
|
-
context 'smell type is matching but smell details are not' do
|
|
96
|
+
context 'when smell type is matching but smell details are not' do
|
|
102
97
|
let(:smelly_code) { 'def double_thing() @other.thing.foo + @other.thing.foo end' }
|
|
103
98
|
let(:matcher) { described_class.new(:DuplicateMethodCall, name: 'foo', count: 15) }
|
|
104
99
|
|
|
105
100
|
it 'is falsey' do
|
|
106
|
-
expect(matcher.
|
|
101
|
+
expect(matcher).not_to be_matches(smelly_code)
|
|
107
102
|
end
|
|
108
103
|
|
|
109
104
|
it 'sets the proper error message' do
|
|
@@ -130,15 +125,15 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
130
125
|
end
|
|
131
126
|
end
|
|
132
127
|
|
|
133
|
-
context '
|
|
134
|
-
before do
|
|
135
|
-
default_config = Reek::SmellDetectors::UnusedPrivateMethod.default_config
|
|
136
|
-
expect(default_config[Reek::SmellConfiguration::ENABLED_KEY]).to be_falsy
|
|
137
|
-
end
|
|
138
|
-
|
|
128
|
+
context 'with a smell that is disabled by default' do
|
|
139
129
|
it 'enables the smell detector to match automatically' do
|
|
130
|
+
default_config = Reek::SmellDetectors::UnusedPrivateMethod.default_config
|
|
140
131
|
src = 'class C; private; def foo; end; end'
|
|
141
|
-
|
|
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
|
|
142
137
|
end
|
|
143
138
|
end
|
|
144
139
|
|
|
@@ -147,13 +142,13 @@ RSpec.describe Reek::Spec::ShouldReekOf do
|
|
|
147
142
|
let(:configured_matcher) { matcher.with_config('accept' => 'x') }
|
|
148
143
|
|
|
149
144
|
it 'uses the passed-in configuration for matching' do
|
|
150
|
-
expect(configured_matcher.
|
|
151
|
-
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')
|
|
152
147
|
end
|
|
153
148
|
|
|
154
149
|
it 'leaves the original matcher intact' do
|
|
155
|
-
expect(configured_matcher.
|
|
156
|
-
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')
|
|
157
152
|
end
|
|
158
153
|
end
|
|
159
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
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
require_lib 'reek/cli/silencer'
|
|
2
|
-
Reek::CLI::Silencer.silently do
|
|
3
|
-
require 'parser/ruby22'
|
|
4
|
-
end
|
|
5
|
-
|
|
6
1
|
require_relative '../spec_helper'
|
|
2
|
+
Reek::CLI::Silencer.without_warnings { require 'parser/ruby25' }
|
|
7
3
|
require_lib 'reek/tree_dresser'
|
|
8
4
|
|
|
9
5
|
RSpec.describe Reek::TreeDresser do
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
describe '#dress' do
|
|
7
|
+
let(:dresser) { described_class.new }
|
|
8
|
+
let(:sexp) do
|
|
9
|
+
Parser::Ruby25.parse('class Klazz; def meth(argument); argument.call_me; end; end')
|
|
10
|
+
end
|
|
11
|
+
let(:dressed_ast) { dresser.dress(sexp, {}) }
|
|
12
|
+
|
|
15
13
|
# The dressed AST looks like this:
|
|
16
14
|
# (class
|
|
17
15
|
# (const nil :Klazz) nil
|
|
@@ -20,14 +18,11 @@ RSpec.describe Reek::TreeDresser do
|
|
|
20
18
|
# (arg :argument))
|
|
21
19
|
# (send
|
|
22
20
|
# (lvar :argument) :call_me)))
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
let(:args_node) { def_node.children[1] }
|
|
28
|
-
let(:send_node) { def_node.children[2] }
|
|
21
|
+
let(:const_node) { dressed_ast.children.first }
|
|
22
|
+
let(:def_node) { dressed_ast.children.last }
|
|
23
|
+
let(:args_node) { def_node.children[1] }
|
|
24
|
+
let(:send_node) { def_node.children[2] }
|
|
29
25
|
|
|
30
|
-
context 'dresses the given sexp' do
|
|
31
26
|
it 'dresses `const` nodes properly' do
|
|
32
27
|
expect(const_node).to be_a Reek::AST::SexpExtensions::ConstNode
|
|
33
28
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'pathname'
|
|
2
2
|
require 'timeout'
|
|
3
|
+
require 'active_support/core_ext/string/strip'
|
|
3
4
|
require_relative '../lib/reek'
|
|
4
5
|
require_relative '../lib/reek/spec'
|
|
5
6
|
require_relative '../lib/reek/ast/ast_node_class_map'
|
|
@@ -7,15 +8,13 @@ require_relative '../lib/reek/configuration/app_configuration'
|
|
|
7
8
|
|
|
8
9
|
require_relative '../samples/paths'
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
14
|
-
end
|
|
11
|
+
begin
|
|
12
|
+
Reek::CLI::Silencer.without_warnings { require 'pry-byebug' }
|
|
13
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
require '
|
|
18
|
-
|
|
16
|
+
require 'factory_bot'
|
|
17
|
+
FactoryBot.find_definitions
|
|
19
18
|
|
|
20
19
|
# Simple helpers for our specs.
|
|
21
20
|
module Helpers
|
|
@@ -75,7 +74,7 @@ end
|
|
|
75
74
|
RSpec.configure do |config|
|
|
76
75
|
config.filter_run :focus
|
|
77
76
|
config.run_all_when_everything_filtered = true
|
|
78
|
-
config.include
|
|
77
|
+
config.include FactoryBot::Syntax::Methods
|
|
79
78
|
config.include Helpers
|
|
80
79
|
|
|
81
80
|
config.disable_monkey_patching!
|
|
@@ -84,15 +83,6 @@ RSpec.configure do |config|
|
|
|
84
83
|
mocks.verify_partial_doubles = true
|
|
85
84
|
mocks.verify_doubled_constant_names = true
|
|
86
85
|
end
|
|
87
|
-
|
|
88
|
-
# Avoid infinitely running tests. This is mainly useful when running a
|
|
89
|
-
# mutation tester. Set the DEBUG environment variable to something truthy
|
|
90
|
-
# like '1' to disable this and allow using pry without specs failing.
|
|
91
|
-
unless ENV['DEBUG']
|
|
92
|
-
config.around(:each) do |example|
|
|
93
|
-
Timeout.timeout(5, &example)
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
86
|
end
|
|
97
87
|
|
|
98
88
|
RSpec::Matchers.define_negated_matcher :not_reek_of, :reek_of
|
data/tasks/configuration.rake
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
require_relative '../lib/reek/detector_repository'
|
|
2
|
+
require_relative '../lib/reek/configuration/rake_task_converter'
|
|
3
|
+
require_relative '../lib/reek/configuration/app_configuration'
|
|
4
|
+
|
|
2
5
|
require 'yaml'
|
|
3
6
|
|
|
4
7
|
namespace :configuration do
|
|
5
8
|
desc 'Updates the default configuration file when smell defaults change'
|
|
6
9
|
task :update_default_configuration do
|
|
7
|
-
DEFAULT_SMELL_CONFIGURATION = 'defaults.reek'.freeze
|
|
10
|
+
DEFAULT_SMELL_CONFIGURATION = 'docs/defaults.reek.yml'.freeze
|
|
8
11
|
content = Reek::DetectorRepository.smell_types.each_with_object({}) do |klass, hash|
|
|
9
|
-
hash[klass.smell_type] = klass.default_config
|
|
12
|
+
hash[klass.smell_type] = Reek::Configuration::RakeTaskConverter.convert klass.default_config
|
|
13
|
+
end
|
|
14
|
+
File.open(DEFAULT_SMELL_CONFIGURATION, 'w') do |file|
|
|
15
|
+
YAML.dump({ Reek::Configuration::AppConfiguration::DETECTORS_KEY => content }, file)
|
|
10
16
|
end
|
|
11
|
-
File.open(DEFAULT_SMELL_CONFIGURATION, 'w') { |file| YAML.dump(content, file) }
|
|
12
17
|
end
|
|
13
18
|
end
|
|
14
|
-
|
|
15
|
-
task 'test:spec' => 'configuration:update_default_configuration'
|