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
|
@@ -15,13 +15,11 @@ RSpec.describe Reek::CLI::Application do
|
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
let(:path_excluded_in_configuration) do
|
|
19
|
-
SAMPLES_PATH.join('source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb')
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
let(:configuration) { test_configuration_for(CONFIG_PATH.join('with_excluded_paths.reek')) }
|
|
23
|
-
|
|
24
18
|
describe '#execute' do
|
|
19
|
+
let(:path_excluded_in_configuration) do
|
|
20
|
+
SAMPLES_DIR.join('source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb')
|
|
21
|
+
end
|
|
22
|
+
let(:configuration) { test_configuration_for(CONFIGURATION_DIR.join('with_excluded_paths.reek')) }
|
|
25
23
|
let(:command) { instance_double 'Reek::CLI::Command::ReportCommand' }
|
|
26
24
|
let(:app) { described_class.new [] }
|
|
27
25
|
|
|
@@ -34,57 +32,69 @@ RSpec.describe Reek::CLI::Application do
|
|
|
34
32
|
expect(app.execute).to eq 'foo'
|
|
35
33
|
end
|
|
36
34
|
|
|
37
|
-
context 'when no source files given' do
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
end
|
|
35
|
+
context 'when no source files given and input was piped' do
|
|
36
|
+
before do
|
|
37
|
+
allow_any_instance_of(IO).to receive(:tty?).and_return(false)
|
|
38
|
+
end
|
|
42
39
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
it 'uses source from pipe' do
|
|
41
|
+
expected_sources = a_collection_containing_exactly(have_attributes(origin: 'STDIN'))
|
|
42
|
+
app.execute
|
|
43
|
+
expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
|
|
44
|
+
with(sources: expected_sources,
|
|
45
|
+
configuration: Reek::Configuration::AppConfiguration,
|
|
46
|
+
options: Reek::CLI::Options)
|
|
50
47
|
end
|
|
51
48
|
|
|
52
|
-
context '
|
|
53
|
-
|
|
54
|
-
allow_any_instance_of(IO).to receive(:tty?).and_return(true)
|
|
55
|
-
end
|
|
49
|
+
context 'when a stdin filename is provided' do
|
|
50
|
+
let(:app) { described_class.new ['--stdin-filename', 'foo.rb'] }
|
|
56
51
|
|
|
57
|
-
it '
|
|
58
|
-
expected_sources =
|
|
52
|
+
it 'assumes that filename' do
|
|
53
|
+
expected_sources = a_collection_containing_exactly(have_attributes(origin: 'foo.rb'))
|
|
59
54
|
app.execute
|
|
60
55
|
expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
|
|
61
56
|
with(sources: expected_sources,
|
|
62
57
|
configuration: Reek::Configuration::AppConfiguration,
|
|
63
58
|
options: Reek::CLI::Options)
|
|
64
59
|
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
context 'when no source files given and no input was piped' do
|
|
64
|
+
before do
|
|
65
|
+
allow_any_instance_of(IO).to receive(:tty?).and_return(true)
|
|
66
|
+
end
|
|
68
67
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
it 'uses working directory as source' do
|
|
69
|
+
expected_sources = Reek::Source::SourceLocator.new(['.']).sources
|
|
70
|
+
app.execute
|
|
71
|
+
expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
|
|
72
|
+
with(sources: expected_sources,
|
|
73
|
+
configuration: Reek::Configuration::AppConfiguration,
|
|
74
|
+
options: Reek::CLI::Options)
|
|
75
|
+
end
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
new(['.'], configuration: configuration).sources
|
|
79
|
-
expect(expected_sources).not_to include(path_excluded_in_configuration)
|
|
77
|
+
context 'when source files are excluded through configuration' do
|
|
78
|
+
let(:app) { described_class.new ['--config', 'some_file.reek'] }
|
|
80
79
|
|
|
81
|
-
|
|
80
|
+
before do
|
|
81
|
+
allow(Reek::Configuration::AppConfiguration).
|
|
82
|
+
to receive(:from_path).
|
|
83
|
+
with(Pathname.new('some_file.reek')).
|
|
84
|
+
and_return configuration
|
|
85
|
+
end
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
it 'uses configuration for excluded paths' do
|
|
88
|
+
expected_sources = Reek::Source::SourceLocator.
|
|
89
|
+
new(['.'], configuration: configuration).sources
|
|
90
|
+
expect(expected_sources).not_to include(path_excluded_in_configuration)
|
|
91
|
+
|
|
92
|
+
app.execute
|
|
93
|
+
|
|
94
|
+
expect(Reek::CLI::Command::ReportCommand).to have_received(:new).
|
|
95
|
+
with(sources: expected_sources,
|
|
96
|
+
configuration: configuration,
|
|
97
|
+
options: Reek::CLI::Options)
|
|
88
98
|
end
|
|
89
99
|
end
|
|
90
100
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require_relative '../../../spec_helper'
|
|
2
2
|
require_lib 'reek/cli/command/todo_list_command'
|
|
3
3
|
require_lib 'reek/cli/options'
|
|
4
|
+
require_lib 'reek/configuration/app_configuration'
|
|
4
5
|
|
|
5
6
|
RSpec.describe Reek::CLI::Command::TodoListCommand do
|
|
6
7
|
let(:nil_check) { build :smell_detector, smell_type: :NilCheck }
|
|
@@ -21,7 +22,7 @@ RSpec.describe Reek::CLI::Command::TodoListCommand do
|
|
|
21
22
|
allow(File).to receive(:write).with(described_class::FILE_NAME, String)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
|
-
context 'smells found' do
|
|
25
|
+
context 'when smells are found' do
|
|
25
26
|
let(:source_file) { SMELLY_FILE }
|
|
26
27
|
|
|
27
28
|
it 'shows a proper message' do
|
|
@@ -37,14 +38,15 @@ RSpec.describe Reek::CLI::Command::TodoListCommand do
|
|
|
37
38
|
it 'writes a todo file with exclusions for each smell' do
|
|
38
39
|
Reek::CLI::Silencer.silently { command.execute }
|
|
39
40
|
expected_yaml = {
|
|
40
|
-
|
|
41
|
-
'
|
|
41
|
+
Reek::Configuration::AppConfiguration::DETECTORS_KEY =>
|
|
42
|
+
{ 'UncommunicativeMethodName' => { 'exclude' => ['Smelly#x'] },
|
|
43
|
+
'UncommunicativeVariableName' => { 'exclude' => ['Smelly#x'] } }
|
|
42
44
|
}.to_yaml
|
|
43
45
|
expect(File).to have_received(:write).with(described_class::FILE_NAME, expected_yaml)
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
context 'no smells found' do
|
|
49
|
+
context 'when no smells re found' do
|
|
48
50
|
let(:source_file) { CLEAN_FILE }
|
|
49
51
|
|
|
50
52
|
it 'shows a proper message' do
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require_relative '../../spec_helper'
|
|
2
|
+
require_lib 'reek/cli/silencer'
|
|
3
|
+
|
|
4
|
+
RSpec.describe Reek::CLI::Silencer do
|
|
5
|
+
describe '.silently' do
|
|
6
|
+
it 'blocks output from the block on $stdout' do
|
|
7
|
+
expect { described_class.silently { puts 'Hi!' } }.not_to output.to_stdout
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'blocks output from the block on $stderr' do
|
|
11
|
+
expect { described_class.silently { warn 'Hi!' } }.not_to output.to_stderr
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'restores output on $stdout after the block' do
|
|
15
|
+
expect do
|
|
16
|
+
described_class.silently { puts 'Hi!' }
|
|
17
|
+
puts 'there!'
|
|
18
|
+
end.to output("there!\n").to_stdout
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'restores output on $stderr after the block' do
|
|
22
|
+
expect do
|
|
23
|
+
described_class.silently { warn 'Hi!' }
|
|
24
|
+
warn 'there!'
|
|
25
|
+
end.to output("there!\n").to_stderr
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -3,7 +3,7 @@ require_lib 'reek/code_comment'
|
|
|
3
3
|
|
|
4
4
|
RSpec.describe Reek::CodeComment do
|
|
5
5
|
context 'with an empty comment' do
|
|
6
|
-
let(:comment) {
|
|
6
|
+
let(:comment) { build(:code_comment, comment: '') }
|
|
7
7
|
|
|
8
8
|
it 'is not descriptive' do
|
|
9
9
|
expect(comment).not_to be_descriptive
|
|
@@ -14,33 +14,33 @@ RSpec.describe Reek::CodeComment do
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
describe '#descriptive' do
|
|
18
18
|
it 'rejects an empty comment' do
|
|
19
|
-
comment =
|
|
19
|
+
comment = build(:code_comment, comment: '#')
|
|
20
20
|
expect(comment).not_to be_descriptive
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it 'rejects a 1-word comment' do
|
|
24
|
-
comment =
|
|
24
|
+
comment = build(:code_comment, comment: "# alpha\n# ")
|
|
25
25
|
expect(comment).not_to be_descriptive
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
it 'accepts a 2-word comment' do
|
|
29
|
-
comment =
|
|
29
|
+
comment = build(:code_comment, comment: '# alpha bravo ')
|
|
30
30
|
expect(comment).to be_descriptive
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it 'accepts a multi-word comment' do
|
|
34
|
-
comment =
|
|
34
|
+
comment = build(:code_comment, comment: "# alpha bravo \n# charlie \n # delta ")
|
|
35
35
|
expect(comment).to be_descriptive
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
describe 'good comment config' do
|
|
40
40
|
it 'parses hashed options' do
|
|
41
41
|
comment = '# :reek:DuplicateMethodCall { enabled: false }'
|
|
42
|
-
config =
|
|
43
|
-
|
|
42
|
+
config = build(:code_comment,
|
|
43
|
+
comment: comment).config
|
|
44
44
|
|
|
45
45
|
expect(config).to include('DuplicateMethodCall')
|
|
46
46
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
|
@@ -49,8 +49,8 @@ RSpec.describe Reek::CodeComment do
|
|
|
49
49
|
|
|
50
50
|
it "supports hashed options with the legacy separator ':' after the smell detector" do
|
|
51
51
|
comment = '# :reek:DuplicateMethodCall: { enabled: false }'
|
|
52
|
-
config =
|
|
53
|
-
|
|
52
|
+
config = build(:code_comment,
|
|
53
|
+
comment: comment).config
|
|
54
54
|
|
|
55
55
|
expect(config).to include('DuplicateMethodCall')
|
|
56
56
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
|
@@ -62,7 +62,7 @@ RSpec.describe Reek::CodeComment do
|
|
|
62
62
|
# :reek:DuplicateMethodCall { enabled: false }
|
|
63
63
|
# :reek:NestedIterators { enabled: true }
|
|
64
64
|
EOF
|
|
65
|
-
config =
|
|
65
|
+
config = build(:code_comment, comment: comment).config
|
|
66
66
|
|
|
67
67
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
|
68
68
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
|
@@ -75,7 +75,7 @@ RSpec.describe Reek::CodeComment do
|
|
|
75
75
|
comment = <<-EOF
|
|
76
76
|
#:reek:DuplicateMethodCall { enabled: false } and :reek:NestedIterators { enabled: true }
|
|
77
77
|
EOF
|
|
78
|
-
config =
|
|
78
|
+
config = build(:code_comment, comment: comment).config
|
|
79
79
|
|
|
80
80
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
|
81
81
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
|
@@ -86,7 +86,7 @@ RSpec.describe Reek::CodeComment do
|
|
|
86
86
|
|
|
87
87
|
it 'parses multiple unhashed options on the same line' do
|
|
88
88
|
comment = '# :reek:DuplicateMethodCall and :reek:NestedIterators'
|
|
89
|
-
config =
|
|
89
|
+
config = build(:code_comment, comment: comment).config
|
|
90
90
|
|
|
91
91
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
|
92
92
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
|
@@ -97,7 +97,7 @@ RSpec.describe Reek::CodeComment do
|
|
|
97
97
|
|
|
98
98
|
it 'disables the smell if no options are specifed' do
|
|
99
99
|
comment = '# :reek:DuplicateMethodCall'
|
|
100
|
-
config =
|
|
100
|
+
config = build(:code_comment, comment: comment).config
|
|
101
101
|
|
|
102
102
|
expect(config).to include('DuplicateMethodCall')
|
|
103
103
|
expect(config['DuplicateMethodCall']).to include('enabled')
|
|
@@ -105,8 +105,8 @@ RSpec.describe Reek::CodeComment do
|
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
it 'ignores smells after a space' do
|
|
108
|
-
config =
|
|
109
|
-
|
|
108
|
+
config = build(:code_comment,
|
|
109
|
+
comment: '# :reek: DuplicateMethodCall').config
|
|
110
110
|
expect(config).not_to include('DuplicateMethodCall')
|
|
111
111
|
end
|
|
112
112
|
|
|
@@ -117,7 +117,7 @@ RSpec.describe Reek::CodeComment do
|
|
|
117
117
|
# :reek:NestedIterators { enabled: true }
|
|
118
118
|
# comment
|
|
119
119
|
EOF
|
|
120
|
-
comment =
|
|
120
|
+
comment = build(:code_comment, comment: original_comment)
|
|
121
121
|
|
|
122
122
|
expect(comment.send(:sanitized_comment)).to eq('Actual comment')
|
|
123
123
|
end
|
|
@@ -125,66 +125,59 @@ RSpec.describe Reek::CodeComment do
|
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
RSpec.describe Reek::CodeComment::CodeCommentValidator do
|
|
128
|
-
context '
|
|
128
|
+
context 'when the comment contains an unknown detector name' do
|
|
129
129
|
it 'raises BadDetectorInCommentError' do
|
|
130
130
|
expect do
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
build(:code_comment,
|
|
132
|
+
comment: '# :reek:DoesNotExist')
|
|
133
133
|
end.to raise_error(Reek::Errors::BadDetectorInCommentError)
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
context 'unparsable detector configuration' do
|
|
137
|
+
context 'when the comment contains an unparsable detector configuration' do
|
|
138
138
|
it 'raises GarbageDetectorConfigurationInCommentError' do
|
|
139
139
|
expect do
|
|
140
140
|
comment = '# :reek:UncommunicativeMethodName { thats: a: bad: config }'
|
|
141
|
-
|
|
141
|
+
build(:code_comment, comment: comment)
|
|
142
142
|
end.to raise_error(Reek::Errors::GarbageDetectorConfigurationInCommentError)
|
|
143
143
|
end
|
|
144
144
|
end
|
|
145
145
|
|
|
146
146
|
describe 'validating configuration keys' do
|
|
147
|
-
context 'basic options mispelled' do
|
|
147
|
+
context 'when basic options are mispelled' do
|
|
148
148
|
it 'raises BadDetectorConfigurationKeyInCommentError' do
|
|
149
149
|
expect do
|
|
150
150
|
# exclude -> exlude and enabled -> nabled
|
|
151
151
|
comment = '# :reek:UncommunicativeMethodName { exlude: alfa, nabled: true }'
|
|
152
|
-
|
|
152
|
+
build(:code_comment, comment: comment)
|
|
153
153
|
end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
-
context 'basic options not mispelled' do
|
|
157
|
+
context 'when basic options are not mispelled' do
|
|
158
158
|
it 'does not raise' do
|
|
159
159
|
expect do
|
|
160
160
|
comment = '# :reek:UncommunicativeMethodName { exclude: alfa, enabled: true }'
|
|
161
|
-
|
|
162
|
-
end.not_to raise_error
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it 'does not raise on regexps' do
|
|
166
|
-
expect do
|
|
167
|
-
comment = '# :reek:UncommunicativeMethodName { exclude: !ruby/regexp /alfa/ }'
|
|
168
|
-
FactoryGirl.build(:code_comment, comment: comment)
|
|
161
|
+
build(:code_comment, comment: comment)
|
|
169
162
|
end.not_to raise_error
|
|
170
163
|
end
|
|
171
164
|
end
|
|
172
165
|
|
|
173
|
-
context 'unknown custom options' do
|
|
166
|
+
context 'when unknown custom options are specified' do
|
|
174
167
|
it 'raises BadDetectorConfigurationKeyInCommentError' do
|
|
175
168
|
expect do
|
|
176
169
|
# max_copies -> mx_copies and min_clump_size -> mn_clump_size
|
|
177
170
|
comment = '# :reek:DataClump { mx_copies: 4, mn_clump_size: 3 }'
|
|
178
|
-
|
|
171
|
+
build(:code_comment, comment: comment)
|
|
179
172
|
end.to raise_error(Reek::Errors::BadDetectorConfigurationKeyInCommentError)
|
|
180
173
|
end
|
|
181
174
|
end
|
|
182
175
|
|
|
183
|
-
context 'valid custom options' do
|
|
176
|
+
context 'when valid custom options are specified' do
|
|
184
177
|
it 'does not raise' do
|
|
185
178
|
expect do
|
|
186
179
|
comment = '# :reek:DataClump { max_copies: 4, min_clump_size: 3 }'
|
|
187
|
-
|
|
180
|
+
build(:code_comment, comment: comment)
|
|
188
181
|
end.not_to raise_error
|
|
189
182
|
end
|
|
190
183
|
end
|
|
@@ -8,8 +8,8 @@ require_lib 'reek/configuration/excluded_paths'
|
|
|
8
8
|
RSpec.describe Reek::Configuration::AppConfiguration do
|
|
9
9
|
describe 'factory methods' do
|
|
10
10
|
let(:expected_excluded_paths) do
|
|
11
|
-
[
|
|
12
|
-
|
|
11
|
+
[SAMPLES_DIR.join('two_smelly_files'),
|
|
12
|
+
SAMPLES_DIR.join('source_with_non_ruby_files')]
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
let(:expected_default_directive) do
|
|
@@ -17,32 +17,35 @@ RSpec.describe Reek::Configuration::AppConfiguration do
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
let(:expected_directory_directives) do
|
|
20
|
-
{
|
|
20
|
+
{ SAMPLES_DIR.join('three_clean_files') =>
|
|
21
21
|
{ Reek::SmellDetectors::UtilityFunction => { 'enabled' => false } } }
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
let(:default_directive_value) do
|
|
25
|
-
{
|
|
25
|
+
{ described_class::DETECTORS_KEY =>
|
|
26
|
+
{ 'IrresponsibleModule' => { 'enabled' => false } } }
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
let(:directory_directives_value) do
|
|
29
|
-
{
|
|
30
|
-
{ '
|
|
30
|
+
{ described_class::DIRECTORIES_KEY =>
|
|
31
|
+
{ 'samples/three_clean_files' =>
|
|
32
|
+
{ 'UtilityFunction' => { 'enabled' => false } } } }
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
let(:exclude_paths_value) do
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
{ described_class::EXCLUDE_PATHS_KEY =>
|
|
37
|
+
['samples/two_smelly_files',
|
|
38
|
+
'samples/source_with_non_ruby_files'] }
|
|
36
39
|
end
|
|
37
40
|
|
|
38
41
|
let(:combined_value) do
|
|
39
42
|
directory_directives_value.
|
|
40
43
|
merge(default_directive_value).
|
|
41
|
-
merge(
|
|
44
|
+
merge(exclude_paths_value)
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
describe '#from_path' do
|
|
45
|
-
let(:full_configuration_path) {
|
|
48
|
+
let(:full_configuration_path) { CONFIGURATION_DIR.join('full_configuration.reek') }
|
|
46
49
|
|
|
47
50
|
it 'properly loads configuration and processes it' do
|
|
48
51
|
config = described_class.from_path full_configuration_path
|
|
@@ -75,36 +78,40 @@ RSpec.describe Reek::Configuration::AppConfiguration do
|
|
|
75
78
|
end
|
|
76
79
|
|
|
77
80
|
describe '#directive_for' do
|
|
78
|
-
context 'multiple directory directives and no default directive present' do
|
|
81
|
+
context 'with multiple directory directives and no default directive present' do
|
|
79
82
|
let(:source_via) { 'samples/three_clean_files/dummy.rb' }
|
|
80
|
-
let(:baz_config) { {
|
|
81
|
-
let(:bang_config) { {
|
|
83
|
+
let(:baz_config) { { IrresponsibleModule: { enabled: false } } }
|
|
84
|
+
let(:bang_config) { { Attribute: { enabled: true } } }
|
|
85
|
+
let(:expected_result) { { Reek::SmellDetectors::Attribute => { enabled: true } } }
|
|
82
86
|
|
|
83
87
|
let(:directory_directives) do
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
{ described_class::DIRECTORIES_KEY =>
|
|
89
|
+
{
|
|
90
|
+
'samples/two_smelly_files' => baz_config,
|
|
91
|
+
'samples/three_clean_files' => bang_config
|
|
92
|
+
} }
|
|
88
93
|
end
|
|
89
94
|
|
|
90
95
|
it 'returns the corresponding directive' do
|
|
91
96
|
configuration = described_class.from_hash directory_directives
|
|
92
|
-
expect(configuration.directive_for(source_via)).to eq
|
|
97
|
+
expect(configuration.directive_for(source_via)).to eq expected_result
|
|
93
98
|
end
|
|
94
99
|
end
|
|
95
100
|
|
|
96
|
-
context 'directory directive and default directive present' do
|
|
101
|
+
context 'with directory directive and default directive present' do
|
|
97
102
|
let(:directory) { 'spec/samples/two_smelly_files/' }
|
|
98
|
-
let(:
|
|
99
|
-
|
|
100
|
-
let(:
|
|
103
|
+
let(:source_via) { "#{directory}/dummy.rb" }
|
|
104
|
+
|
|
105
|
+
let(:configuration_as_hash) do
|
|
101
106
|
{
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
described_class::DIRECTORIES_KEY =>
|
|
108
|
+
{ directory => { TooManyStatements: { max_statements: 8 } } },
|
|
109
|
+
described_class::DETECTORS_KEY => {
|
|
110
|
+
IrresponsibleModule: { enabled: false },
|
|
111
|
+
TooManyStatements: { max_statements: 15 }
|
|
112
|
+
}
|
|
104
113
|
}
|
|
105
114
|
end
|
|
106
|
-
let(:source_via) { "#{directory}/dummy.rb" }
|
|
107
|
-
let(:configuration_as_hash) { directory_directives.merge(default_directive) }
|
|
108
115
|
|
|
109
116
|
it 'returns the directory directive with the default directive reverse-merged' do
|
|
110
117
|
configuration = described_class.from_hash configuration_as_hash
|
|
@@ -116,18 +123,24 @@ RSpec.describe Reek::Configuration::AppConfiguration do
|
|
|
116
123
|
end
|
|
117
124
|
end
|
|
118
125
|
|
|
119
|
-
context '
|
|
126
|
+
context 'with a path not covered by a directory directive but a default directive present' do
|
|
120
127
|
let(:source_via) { 'spec/samples/three_clean_files/dummy.rb' }
|
|
121
|
-
|
|
122
|
-
let(:
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
|
|
129
|
+
let(:configuration_as_hash) do
|
|
130
|
+
{
|
|
131
|
+
described_class::DETECTORS_KEY => {
|
|
132
|
+
IrresponsibleModule: { enabled: false }
|
|
133
|
+
},
|
|
134
|
+
described_class::DIRECTORIES_KEY =>
|
|
135
|
+
{ 'spec/samples/two_smelly_files' => { Attribute: { enabled: false } } }
|
|
136
|
+
}
|
|
125
137
|
end
|
|
126
|
-
|
|
138
|
+
|
|
139
|
+
let(:expected_result) { { Reek::SmellDetectors::IrresponsibleModule => { enabled: false } } }
|
|
127
140
|
|
|
128
141
|
it 'returns the default directive' do
|
|
129
142
|
configuration = described_class.from_hash configuration_as_hash
|
|
130
|
-
expect(configuration.directive_for(source_via)).to eq
|
|
143
|
+
expect(configuration.directive_for(source_via)).to eq expected_result
|
|
131
144
|
end
|
|
132
145
|
end
|
|
133
146
|
end
|