reek 2.0.4 → 3.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/.gitignore +13 -0
- data/.rubocop.yml +47 -0
- data/.travis.yml +31 -0
- data/.yardopts +3 -6
- data/CHANGELOG +24 -0
- data/CONTRIBUTING.md +111 -0
- data/Gemfile +16 -0
- data/README.md +112 -59
- data/bin/reek +2 -2
- data/config/cucumber.yml +3 -0
- data/config/defaults.reek +0 -1
- data/docs/API.md +79 -0
- data/docs/Attribute.md +43 -0
- data/docs/Basic-Smell-Options.md +44 -0
- data/docs/Boolean-Parameter.md +52 -0
- data/docs/Class-Variable.md +40 -0
- data/docs/Code-Smells.md +34 -0
- data/docs/Command-Line-Options.md +84 -0
- data/docs/Configuration-Files.md +49 -0
- data/docs/Control-Couple.md +22 -0
- data/docs/Control-Parameter.md +29 -0
- data/docs/Data-Clump.md +44 -0
- data/docs/Duplicate-Method-Call.md +49 -0
- data/docs/Feature-Envy.md +49 -0
- data/docs/How-reek-works-internally.md +114 -0
- data/docs/Irresponsible-Module.md +39 -0
- data/docs/Large-Class.md +20 -0
- data/docs/Long-Parameter-List.md +38 -0
- data/docs/Long-Yield-List.md +36 -0
- data/docs/Module-Initialize.md +62 -0
- data/docs/Nested-Iterators.md +38 -0
- data/docs/Nil-Check.md +39 -0
- data/docs/Prima-Donna-Method.md +53 -0
- data/docs/RSpec-matchers.md +137 -0
- data/docs/Rake-Task.md +58 -0
- data/docs/Reek-Driven-Development.md +37 -0
- data/docs/Repeated-Conditional.md +44 -0
- data/docs/Simulated-Polymorphism.md +16 -0
- data/docs/Smell-Suppression.md +32 -0
- data/docs/Too-Many-Instance-Variables.md +43 -0
- data/docs/Too-Many-Methods.md +55 -0
- data/docs/Too-Many-Statements.md +50 -0
- data/docs/Uncommunicative-Method-Name.md +24 -0
- data/docs/Uncommunicative-Module-Name.md +23 -0
- data/docs/Uncommunicative-Name.md +16 -0
- data/docs/Uncommunicative-Parameter-Name.md +24 -0
- data/docs/Uncommunicative-Variable-Name.md +24 -0
- data/docs/Unused-Parameters.md +27 -0
- data/docs/Utility-Function.md +44 -0
- data/docs/Versioning-Policy.md +7 -0
- data/docs/YAML-Reports.md +111 -0
- data/docs/yard_plugin.rb +14 -0
- data/features/{ruby_api/api.feature → command_line_interface/basic_usage.feature} +6 -5
- data/features/command_line_interface/options.feature +1 -0
- data/features/command_line_interface/smell_selection.feature +4 -8
- data/features/command_line_interface/smells_count.feature +25 -32
- data/features/command_line_interface/stdin.feature +2 -2
- data/features/configuration_files/masking_smells.feature +30 -41
- data/features/configuration_files/overrides_defaults.feature +5 -3
- data/features/configuration_loading.feature +26 -23
- data/features/programmatic_access.feature +43 -0
- data/features/rake_task/rake_task.feature +25 -22
- data/features/reports/json.feature +24 -26
- data/features/reports/reports.feature +77 -103
- data/features/reports/yaml.feature +26 -20
- data/features/samples.feature +26 -31
- data/features/step_definitions/.rubocop.yml +5 -0
- data/features/step_definitions/reek_steps.rb +16 -28
- data/features/step_definitions/sample_file_steps.rb +158 -0
- data/features/support/env.rb +16 -27
- data/lib/reek/{source → ast}/ast_node_class_map.rb +11 -12
- data/lib/reek/ast/node.rb +132 -0
- data/lib/reek/{core → ast}/object_refs.rb +2 -1
- data/lib/reek/ast/reference_collector.rb +32 -0
- data/lib/reek/{source → ast}/sexp_extensions.rb +43 -7
- data/lib/reek/ast/sexp_formatter.rb +31 -0
- data/lib/reek/cli/application.rb +5 -4
- data/lib/reek/cli/command.rb +2 -1
- data/lib/reek/cli/input.rb +6 -5
- data/lib/reek/cli/option_interpreter.rb +13 -9
- data/lib/reek/cli/options.rb +16 -8
- data/lib/reek/cli/reek_command.rb +4 -3
- data/lib/reek/cli/silencer.rb +14 -0
- data/lib/reek/{core → cli}/warning_collector.rb +2 -1
- data/lib/reek/code_comment.rb +36 -0
- data/lib/reek/configuration/app_configuration.rb +18 -3
- data/lib/reek/configuration/configuration_file_finder.rb +18 -32
- data/lib/reek/{core → context}/code_context.rb +8 -6
- data/lib/reek/{core → context}/method_context.rb +11 -5
- data/lib/reek/{core → context}/module_context.rb +9 -4
- data/lib/reek/{core/stop_context.rb → context/root_context.rb} +4 -2
- data/lib/reek/{core → context}/singleton_method_context.rb +3 -6
- data/lib/reek/examiner.rb +32 -29
- data/lib/reek/report/formatter.rb +70 -0
- data/lib/reek/report/heading_formatter.rb +45 -0
- data/lib/reek/report/location_formatter.rb +35 -0
- data/lib/reek/report/report.rb +198 -0
- data/lib/reek/smells/attribute.rb +41 -11
- data/lib/reek/smells/boolean_parameter.rb +4 -2
- data/lib/reek/smells/class_variable.rb +4 -2
- data/lib/reek/smells/control_parameter.rb +4 -2
- data/lib/reek/smells/data_clump.rb +4 -3
- data/lib/reek/smells/duplicate_method_call.rb +15 -5
- data/lib/reek/smells/feature_envy.rb +8 -2
- data/lib/reek/smells/irresponsible_module.rb +13 -8
- data/lib/reek/smells/long_parameter_list.rb +6 -4
- data/lib/reek/smells/long_yield_list.rb +4 -2
- data/lib/reek/smells/module_initialize.rb +4 -2
- data/lib/reek/smells/nested_iterators.rb +4 -2
- data/lib/reek/smells/nil_check.rb +6 -3
- data/lib/reek/smells/prima_donna_method.rb +21 -12
- data/lib/reek/smells/repeated_conditional.rb +7 -4
- data/lib/reek/{core → smells}/smell_configuration.rb +3 -1
- data/lib/reek/smells/smell_detector.rb +11 -5
- data/lib/reek/{core → smells}/smell_repository.rb +9 -5
- data/lib/reek/smells/smell_warning.rb +101 -0
- data/lib/reek/smells/too_many_instance_variables.rb +4 -2
- data/lib/reek/smells/too_many_methods.rb +4 -2
- data/lib/reek/smells/too_many_statements.rb +4 -2
- data/lib/reek/smells/uncommunicative_method_name.rb +4 -2
- data/lib/reek/smells/uncommunicative_module_name.rb +4 -2
- data/lib/reek/smells/uncommunicative_parameter_name.rb +4 -2
- data/lib/reek/smells/uncommunicative_variable_name.rb +4 -2
- data/lib/reek/smells/unused_parameters.rb +4 -2
- data/lib/reek/smells/utility_function.rb +11 -22
- data/lib/reek/smells.rb +24 -11
- data/lib/reek/source/source_code.rb +69 -12
- data/lib/reek/source/source_locator.rb +34 -19
- data/lib/reek/spec/should_reek.rb +4 -3
- data/lib/reek/spec/should_reek_of.rb +2 -1
- data/lib/reek/spec/should_reek_only_of.rb +4 -3
- data/lib/reek/spec.rb +3 -3
- data/lib/reek/tree_dresser.rb +32 -0
- data/lib/reek/tree_walker.rb +182 -0
- data/lib/reek/version.rb +1 -1
- data/lib/reek.rb +3 -3
- data/reek.gemspec +18 -25
- data/spec/factories/factories.rb +4 -2
- data/spec/gem/updates_spec.rb +1 -1
- data/spec/gem/yard_spec.rb +2 -2
- data/spec/quality/reek_source_spec.rb +3 -3
- data/spec/reek/{source/sexp_node_spec.rb → ast/node_spec.rb} +4 -6
- data/spec/reek/{core → ast}/object_refs_spec.rb +4 -6
- data/spec/reek/{source → ast}/reference_collector_spec.rb +27 -19
- data/spec/reek/{source → ast}/sexp_extensions_spec.rb +7 -19
- data/spec/reek/{source → ast}/sexp_formatter_spec.rb +13 -8
- data/spec/reek/cli/option_interpreter_spec.rb +15 -0
- data/spec/reek/cli/options_spec.rb +19 -0
- data/spec/reek/cli/warning_collector_spec.rb +28 -0
- data/spec/reek/{source/code_comment_spec.rb → code_comment_spec.rb} +19 -17
- data/spec/reek/configuration/app_configuration_spec.rb +37 -26
- data/spec/reek/configuration/configuration_file_finder_spec.rb +67 -21
- data/spec/reek/{core → context}/code_context_spec.rb +18 -21
- data/spec/reek/{core → context}/method_context_spec.rb +33 -27
- data/spec/reek/{core → context}/module_context_spec.rb +5 -7
- data/spec/reek/context/root_context_spec.rb +14 -0
- data/spec/reek/context/singleton_method_context_spec.rb +17 -0
- data/spec/reek/examiner_spec.rb +9 -50
- data/spec/reek/{cli → report}/html_report_spec.rb +6 -9
- data/spec/reek/report/json_report_spec.rb +20 -0
- data/spec/reek/{cli → report}/text_report_spec.rb +16 -19
- data/spec/reek/report/xml_report_spec.rb +34 -0
- data/spec/reek/report/yaml_report_spec.rb +20 -0
- data/spec/reek/smells/attribute_spec.rb +93 -88
- data/spec/reek/smells/behaves_like_variable_detector.rb +1 -1
- data/spec/reek/smells/boolean_parameter_spec.rb +31 -5
- data/spec/reek/smells/class_variable_spec.rb +10 -10
- data/spec/reek/smells/control_parameter_spec.rb +5 -5
- data/spec/reek/smells/data_clump_spec.rb +6 -6
- data/spec/reek/smells/duplicate_method_call_spec.rb +7 -7
- data/spec/reek/smells/feature_envy_spec.rb +12 -13
- data/spec/reek/smells/irresponsible_module_spec.rb +28 -32
- data/spec/reek/smells/long_parameter_list_spec.rb +7 -7
- data/spec/reek/smells/long_yield_list_spec.rb +6 -6
- data/spec/reek/smells/module_initialize_spec.rb +4 -4
- data/spec/reek/smells/nested_iterators_spec.rb +6 -6
- data/spec/reek/smells/nil_check_spec.rb +6 -6
- data/spec/reek/smells/prima_donna_method_spec.rb +8 -5
- data/spec/reek/smells/repeated_conditional_spec.rb +18 -17
- data/spec/reek/{core → smells}/smell_configuration_spec.rb +5 -7
- data/spec/reek/smells/smell_detector_shared.rb +6 -7
- data/spec/reek/smells/smell_repository_spec.rb +29 -0
- data/spec/reek/{smell_warning_spec.rb → smells/smell_warning_spec.rb} +7 -9
- data/spec/reek/smells/too_many_instance_variables_spec.rb +5 -5
- data/spec/reek/smells/too_many_methods_spec.rb +12 -8
- data/spec/reek/smells/too_many_statements_spec.rb +10 -9
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +5 -5
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +8 -8
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +18 -6
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +10 -7
- data/spec/reek/smells/unused_parameters_spec.rb +4 -4
- data/spec/reek/smells/utility_function_spec.rb +65 -39
- data/spec/reek/source/source_code_spec.rb +10 -10
- data/spec/reek/source/source_locator_spec.rb +30 -0
- data/spec/reek/spec/should_reek_of_spec.rb +9 -25
- data/spec/reek/spec/should_reek_only_of_spec.rb +4 -7
- data/spec/reek/spec/should_reek_spec.rb +4 -32
- data/spec/reek/tree_dresser_spec.rb +16 -0
- data/spec/reek/{core/tree_walker_spec.rb → tree_walker_spec.rb} +5 -7
- data/spec/samples/checkstyle.xml +2 -0
- data/spec/samples/configuration/with_excluded_paths.reek +4 -0
- data/spec/samples/{overrides/masked/lower.reek → masked_by_dotfile/.reek} +3 -1
- data/spec/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +5 -0
- data/spec/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +2 -0
- data/spec/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +6 -0
- data/spec/samples/{ruby20_syntax.rb → unusual_syntax.rb} +8 -0
- data/spec/spec_helper.rb +21 -10
- data/tasks/develop.rake +2 -2
- data/tasks/reek.rake +1 -1
- metadata +158 -141
- data/features/support/hooks.rb +0 -15
- data/lib/reek/cli/report/formatter.rb +0 -69
- data/lib/reek/cli/report/heading_formatter.rb +0 -45
- data/lib/reek/cli/report/location_formatter.rb +0 -34
- data/lib/reek/cli/report/report.rb +0 -131
- data/lib/reek/core/tree_walker.rb +0 -180
- data/lib/reek/smell_warning.rb +0 -87
- data/lib/reek/source/ast_node.rb +0 -38
- data/lib/reek/source/code_comment.rb +0 -37
- data/lib/reek/source/core_extras.rb +0 -46
- data/lib/reek/source/reference_collector.rb +0 -27
- data/lib/reek/source/sexp_formatter.rb +0 -22
- data/lib/reek/source/sexp_node.rb +0 -79
- data/lib/reek/source/source_file.rb +0 -16
- data/lib/reek/source/source_repository.rb +0 -45
- data/lib/reek/source/tree_dresser.rb +0 -24
- data/lib/reek/source.rb +0 -16
- data/spec/reek/cli/json_report_spec.rb +0 -20
- data/spec/reek/cli/option_interperter_spec.rb +0 -14
- data/spec/reek/cli/yaml_report_spec.rb +0 -23
- data/spec/reek/core/singleton_method_context_spec.rb +0 -9
- data/spec/reek/core/smell_repository_spec.rb +0 -17
- data/spec/reek/core/stop_context_spec.rb +0 -17
- data/spec/reek/core/warning_collector_spec.rb +0 -30
- data/spec/reek/source/object_source_spec.rb +0 -20
- data/spec/reek/source/tree_dresser_spec.rb +0 -18
- data/spec/samples/config/allow_duplication.reek +0 -3
- data/spec/samples/config/deeper_nested_iterators.reek +0 -3
- data/spec/samples/configuration_loading/minimal_dirty.rb +0 -4
- data/spec/samples/configuration_loading/reek-test-run-disable_smells.reek +0 -7
- data/spec/samples/configuration_loading/reek-test-run-enable_smells.reek +0 -7
- data/spec/samples/corrupt_config_file/corrupt.reek +0 -1
- data/spec/samples/corrupt_config_file/dirty.rb +0 -8
- data/spec/samples/demo/demo.rb +0 -8
- data/spec/samples/empty_config_file/dirty.rb +0 -8
- data/spec/samples/empty_config_file/empty.reek +0 -0
- data/spec/samples/inline_config/dirty.rb +0 -16
- data/spec/samples/inline_config/masked.reek +0 -7
- data/spec/samples/mask_some/dirty.rb +0 -8
- data/spec/samples/mask_some/some.reek +0 -8
- data/spec/samples/masked/dirty.rb +0 -8
- data/spec/samples/masked/masked.reek +0 -5
- data/spec/samples/minimal_smelly_and_masked/config.reek +0 -7
- data/spec/samples/minimal_smelly_and_masked/minimal_dirty.rb +0 -4
- data/spec/samples/mixed_results/clean_one.rb +0 -7
- data/spec/samples/mixed_results/clean_three.rb +0 -7
- data/spec/samples/mixed_results/clean_two.rb +0 -7
- data/spec/samples/mixed_results/dirty_one.rb +0 -8
- data/spec/samples/mixed_results/dirty_two.rb +0 -8
- data/spec/samples/not_quite_masked/dirty.rb +0 -8
- data/spec/samples/not_quite_masked/masked.reek +0 -5
- data/spec/samples/not_quite_masked/smelly.rb +0 -3
- data/spec/samples/one_smelly_file/dirty.rb +0 -3
- data/spec/samples/overrides/masked/dirty.rb +0 -8
- data/spec/samples/overrides/upper.reek +0 -5
- data/spec/samples/overrides_defaults/camel_case.rb +0 -14
- data/spec/samples/overrides_defaults/config.reek +0 -6
- data/spec/samples/ruby21_syntax.rb +0 -5
- data/spec/samples/standard_smelly/dirty.rb +0 -8
- data/spec/samples/standard_smelly/minimal_dirty.rb +0 -4
- data/spec/samples/three_smelly_files/dirty_one.rb +0 -3
- data/spec/samples/three_smelly_files/dirty_three.rb +0 -5
- data/spec/samples/three_smelly_files/dirty_two.rb +0 -4
- /data/spec/samples/{simple_configuration.reek → configuration/simple_configuration.reek} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Repeated Conditional
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
`Repeated Conditional` is a special case of [Simulated Polymorphism](Simulated-Polymorphism.md). Basically it means you are checking the same value throughout a single class and take decisions based on this.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
Given
|
|
10
|
+
|
|
11
|
+
```Ruby
|
|
12
|
+
class RepeatedConditionals
|
|
13
|
+
attr_accessor :switch
|
|
14
|
+
|
|
15
|
+
def repeat_1
|
|
16
|
+
puts "Repeat 1!" if switch
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def repeat_2
|
|
20
|
+
puts "Repeat 2!" if switch
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def repeat_3
|
|
24
|
+
puts "Repeat 3!" if switch
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`reek` would emit the following warning:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
test.rb -- 4 warnings:
|
|
33
|
+
[5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
`reek`'s `Repeated Conditional` detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
41
|
+
|
|
42
|
+
| Option | Value | Effect |
|
|
43
|
+
| ---------------|-------------|---------|
|
|
44
|
+
| `max_ifs` | integer | The maximum number of identical conditional tests permitted before Reek raises a warning. Defaults to 2. |
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Simulated Polymorphism
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
Simulated Polymorphism occurs when
|
|
6
|
+
|
|
7
|
+
* code uses a case statement (especially on a type field);
|
|
8
|
+
* or code has several if statements in a row (especially if they're comparing against the same value);
|
|
9
|
+
* or code uses instance_of?, kind_of?, is_a?, or === to decide what type it's working with;
|
|
10
|
+
* or multiple conditionals in different places test the same value.
|
|
11
|
+
|
|
12
|
+
Conditional code is hard to read and understand, because the reader must hold more state in his head. When the same value is tested in multiple places throughout an application, any change to the set of possible values will require many methods and classes to change. Tests for the type of an object may indicate that the abstraction represented by that type is not completely defined (or understood).
|
|
13
|
+
|
|
14
|
+
## Current Support in reek
|
|
15
|
+
|
|
16
|
+
`reek` checks for [Repeated Conditional](Repeated-Conditional.md) and for [Nil Check](Nil-Check.md).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## Introduction
|
|
2
|
+
|
|
3
|
+
In some cases, it might be necessary to suppress one or more of `reek`'s smell warnings for a particular method or class.
|
|
4
|
+
|
|
5
|
+
Possible reasons for this could be:
|
|
6
|
+
|
|
7
|
+
* The code is outside of your control and you can't fix it
|
|
8
|
+
* `reek` is not the police. You might have legit reasons why your source code is good as it is.
|
|
9
|
+
|
|
10
|
+
## How to disable smell detection
|
|
11
|
+
|
|
12
|
+
First and foremost, there are the [Basic Smell Options](Basic-Smell-Options.md) you can use.
|
|
13
|
+
|
|
14
|
+
Besides from that, you can use special comments, like so:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
# This method smells of :reek:NestedIterators
|
|
18
|
+
def smelly_method foo
|
|
19
|
+
foo.each {|bar| bar.each {|baz| baz.qux}}
|
|
20
|
+
end
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The method `smelly_method` will not be reported. The general pattern is to put the string ':reek:', followed by the smell class, in a comment before the method or class.
|
|
24
|
+
|
|
25
|
+
It is also possible to specify options for a particular smell detector, like so:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
# :reek:LongParameterList: { max_params: 4 }
|
|
29
|
+
def many_parameters_it_has foo, bar, baz, qux
|
|
30
|
+
# ...
|
|
31
|
+
end
|
|
32
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
## Introduction
|
|
2
|
+
|
|
3
|
+
`Too Many Instance Variables` is a special case of `LargeClass`.
|
|
4
|
+
|
|
5
|
+
## Example
|
|
6
|
+
|
|
7
|
+
Given this configuration
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
TooManyInstanceVariables:
|
|
11
|
+
max_instance_variables: 3
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
and this code:
|
|
15
|
+
|
|
16
|
+
```Ruby
|
|
17
|
+
class TooManyInstanceVariables
|
|
18
|
+
def initialize
|
|
19
|
+
@arg_1 = :dummy
|
|
20
|
+
@arg_2 = :dummy
|
|
21
|
+
@arg_3 = :dummy
|
|
22
|
+
@arg_4 = :dummy
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`reek` would emit the following warning:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
test.rb -- 5 warnings:
|
|
31
|
+
[1]:TooManyInstanceVariables has at least 4 instance variables (TooManyInstanceVariables)
|
|
32
|
+
```
|
|
33
|
+
## Current Support in `reek`
|
|
34
|
+
|
|
35
|
+
`reek` only counts the instance variables you use explicitly like in the example above. Class macros like `attr_accessor` are disregarded.
|
|
36
|
+
|
|
37
|
+
## Configuration
|
|
38
|
+
|
|
39
|
+
`reek`'s `Too Many Instance Variables` detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
40
|
+
|
|
41
|
+
| Option | Value | Effect |
|
|
42
|
+
| ---------------|-------------|---------|
|
|
43
|
+
| max_instance_variables | integer | The maximum number of instance variables that are permitted. Defaults to 9 |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
## Introduction
|
|
2
|
+
|
|
3
|
+
`Too Many Methods` is a special case of `LargeClass`.
|
|
4
|
+
|
|
5
|
+
## Example
|
|
6
|
+
|
|
7
|
+
Given this configuration
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
TooManyMethods:
|
|
11
|
+
max_methods: 3
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
and this code:
|
|
15
|
+
|
|
16
|
+
```Ruby
|
|
17
|
+
class TooManyMethods
|
|
18
|
+
def one; end
|
|
19
|
+
def two; end
|
|
20
|
+
def three; end
|
|
21
|
+
def four; end
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`reek` would emit the following warning:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
test.rb -- 1 warning:
|
|
29
|
+
[1]:TooManyMethods has at least 4 methods (TooManyMethods)
|
|
30
|
+
```
|
|
31
|
+
## Current Support in `reek`
|
|
32
|
+
|
|
33
|
+
`reek` counts all the methods it can find in a `class` - instance *and* class methods. So given `max_methods` from above is 4, this:
|
|
34
|
+
|
|
35
|
+
```Ruby
|
|
36
|
+
class TooManyMethods
|
|
37
|
+
class << self
|
|
38
|
+
def one; end
|
|
39
|
+
def two; end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def three; end
|
|
43
|
+
def four; end
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
would cause reek to emit the same warning as in the example above.
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
|
|
51
|
+
`reek`'s `Too Many Methods` detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
52
|
+
|
|
53
|
+
| Option | Value | Effect |
|
|
54
|
+
| ---------------|-------------|---------|
|
|
55
|
+
| max_methods | integer | The maximum number of methods that are permitted. Defaults to 25 |
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Too Many Statements
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
A method with `Too Many Statements` is any method that has a large number of lines.
|
|
6
|
+
|
|
7
|
+
## Current Support in Reek
|
|
8
|
+
|
|
9
|
+
`Too Many Statements` warns about any method that has more than 5 statements. `reek`'s smell detector for `Too Many Statements` counts +1 for every simple statement in a method and +1 for every statement within a control structure (`if`, `else`, `case`, `when`, `for`, `while`, `until`, `begin`, `rescue`) but it doesn't count the control structure itself.
|
|
10
|
+
|
|
11
|
+
So the following method would score +6 in Reek's statement-counting algorithm:
|
|
12
|
+
|
|
13
|
+
```Ruby
|
|
14
|
+
def parse(arg, argv, &error)
|
|
15
|
+
if !(val = arg) and (argv.empty? or /\A-/ =~ (val = argv[0]))
|
|
16
|
+
return nil, block, nil # +1
|
|
17
|
+
end
|
|
18
|
+
opt = (val = parse_arg(val, &error))[1] # +2
|
|
19
|
+
val = conv_arg(*val) # +3
|
|
20
|
+
if opt and !arg
|
|
21
|
+
argv.shift # +4
|
|
22
|
+
else
|
|
23
|
+
val[0] = nil # +5
|
|
24
|
+
end
|
|
25
|
+
val # +6
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
(You might argue that the two assigments within the first @if@ should count as statements, and that perhaps the nested assignment should count as +2.)
|
|
30
|
+
|
|
31
|
+
## Configuration
|
|
32
|
+
|
|
33
|
+
`reek`'s `Too Many Statements` detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
34
|
+
|
|
35
|
+
| Option | Value | Effect |
|
|
36
|
+
| ---------------|-------------|---------|
|
|
37
|
+
| `max_statements` | integer | The maximum number of statements allowed in a method before a warning is issued. Defaults to 5. |
|
|
38
|
+
|
|
39
|
+
`Too Many Statements`'s default configuration is:
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
---
|
|
43
|
+
TooManyStatements:
|
|
44
|
+
enabled: true
|
|
45
|
+
exclude:
|
|
46
|
+
- initialize
|
|
47
|
+
max_statements: 5
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
By default, `initialize` is not checked for length; any class's constructor can be as long as necessary.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Uncommunicative Method Name
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
An `Uncommunicative Method Name` is a method name that doesn't communicate its intent well enough.
|
|
6
|
+
|
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
|
8
|
+
|
|
9
|
+
## Current Support in reek
|
|
10
|
+
|
|
11
|
+
`Uncommunicative Method Name` checks for:
|
|
12
|
+
|
|
13
|
+
* 1-character names
|
|
14
|
+
* any name ending with a number
|
|
15
|
+
* camelCaseVariableNames
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
`reek`'s Uncommunicative Method Name detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
20
|
+
|
|
21
|
+
| Option | Value | Effect |
|
|
22
|
+
| ---------------|-------------|---------|
|
|
23
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^[a-z]$/, /[0-9]$/, /[A-Z]/]`. |
|
|
24
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. |
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Uncommunicative Module Name
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
An `Uncommunicative Module Name` is a module name that doesn't communicate its intent well enough.
|
|
6
|
+
|
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
|
8
|
+
|
|
9
|
+
## Current Support in reek
|
|
10
|
+
|
|
11
|
+
`Uncommunicative Module Name` checks for:
|
|
12
|
+
|
|
13
|
+
* 1-character names
|
|
14
|
+
* any name ending with a number
|
|
15
|
+
|
|
16
|
+
## Configuration
|
|
17
|
+
|
|
18
|
+
`reek`'s `Uncommunicative Module Name` detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
19
|
+
|
|
20
|
+
| Option | Value | Effect |
|
|
21
|
+
| ---------------|-------------|---------|
|
|
22
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/]`. |
|
|
23
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to `['Inline::C']`.|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Uncommunicative Name
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
An `Uncommunicative Name` is a name that doesn't communicate its intent well enough.
|
|
6
|
+
|
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
|
8
|
+
|
|
9
|
+
## Current Support in Reek
|
|
10
|
+
|
|
11
|
+
`reek` offers four related checks:
|
|
12
|
+
|
|
13
|
+
* [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
|
|
14
|
+
* [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
|
|
15
|
+
* [Uncommunicative Parameter Name](Uncommunicative-Parameter-Name.md)
|
|
16
|
+
* [Uncommunicative Variable Name](Uncommunicative-Variable-Name.md)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Uncommunicative Parameter Name
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
An `Uncommunicative Parameter Name` is a parameter name that doesn't communicate its intent well enough.
|
|
6
|
+
|
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
|
8
|
+
|
|
9
|
+
## Current Support in reek
|
|
10
|
+
|
|
11
|
+
`Uncommunicative Parameter Name` checks for:
|
|
12
|
+
|
|
13
|
+
* 1-character names
|
|
14
|
+
* any name ending with a number
|
|
15
|
+
* camelCaseVariableNames
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
`reek`'s Uncommunicative Parameter Name detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
20
|
+
|
|
21
|
+
| Option | Value | Effect |
|
|
22
|
+
| ---------------|-------------|---------|
|
|
23
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/]@. |
|
|
24
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. |
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Uncommunicative Variable Name
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
An `Uncommunicative Variable Name` is a variable name that doesn't communicate its intent well enough.
|
|
6
|
+
|
|
7
|
+
Poor names make it hard for the reader to build a mental picture of what's going on in the code. They can also be mis-interpreted; and they hurt the flow of reading, because the reader must slow down to interpret the names.
|
|
8
|
+
|
|
9
|
+
## Current Support in Reek
|
|
10
|
+
|
|
11
|
+
`Uncommunicative Variable Name` checks for:
|
|
12
|
+
|
|
13
|
+
* 1-character names
|
|
14
|
+
* any name ending with a number
|
|
15
|
+
* camelCaseVariableNames
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
`reek`'s `Uncommunicative Variable Name` detector supports the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
|
20
|
+
|
|
21
|
+
| Option | Value | Effect |
|
|
22
|
+
| ---------------|-------------|---------|
|
|
23
|
+
| `reject` | array of regular expressions | The set of regular expressions that `reek` uses to check for bad names. Defaults to `[/^.$/, /[0-9]$/, /[A-Z]/]`. |
|
|
24
|
+
| `accept` | array of strings or regular expressions | Name that will be accepted (not reported) even if they match one of the `reject` expressions. Defaults to @['_']@.|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
## Introduction
|
|
2
|
+
|
|
3
|
+
`Unused Parameter` refers to methods with parameters that are unused in scope of the method.
|
|
4
|
+
|
|
5
|
+
Having unused parameters in a method is code smell because leaving dead code in a method can never improve the method and it makes the code confusing to read.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
Given:
|
|
10
|
+
|
|
11
|
+
```Ruby
|
|
12
|
+
class Klass
|
|
13
|
+
def unused_parameters(x,y,z)
|
|
14
|
+
puts x,y # but not z
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`reek` would emit the following warning:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
[2]:Klass#unused_parameters has unused parameter 'z' (UnusedParameters)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
`Unused Parameter` offers the [Basic Smell Options](Basic-Smell-Options.md).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Utility Function
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
A _Utility Function_ is any instance method that has no dependency on the state of the instance.
|
|
6
|
+
|
|
7
|
+
_Utility Function_ is heavily related to _[Feature Envy](Feature-Envy.md)_, please check out the explanation there why _Utility Function_ is something you should care about.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
Given
|
|
12
|
+
|
|
13
|
+
```Ruby
|
|
14
|
+
class UtilityFunction
|
|
15
|
+
def showcase(argument)
|
|
16
|
+
argument.to_s + argument.to_i
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`reek` would report:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
test.rb -- 2 warnings:
|
|
25
|
+
[2]:UtilityFunction#showcase doesn't depend on instance state (UtilityFunction)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Current Support in reek
|
|
29
|
+
|
|
30
|
+
_Utility Function_ will warn about any method that:
|
|
31
|
+
|
|
32
|
+
* is non-empty
|
|
33
|
+
* does not override an inherited method
|
|
34
|
+
* calls at least one method on another object
|
|
35
|
+
* doesn't use any of self's instance variables
|
|
36
|
+
* doesn't use any of self's methods
|
|
37
|
+
|
|
38
|
+
## Differences to _Feature Envy_
|
|
39
|
+
|
|
40
|
+
_[Feature Envy](Feature-Envy.md)_ is only triggered if there are some references to self and _Utility Function_ is triggered if there are no references to self.
|
|
41
|
+
|
|
42
|
+
## Configuration
|
|
43
|
+
|
|
44
|
+
`reek`'s _Utility Function_ detector supports the [Basic Smell Options](Basic-Smell-Options.md).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Versioning Policy
|
|
2
|
+
|
|
3
|
+
* CLI interface: Adding options is a non-breaking change, and would warrant an update of the minor version. Removing options is a breaking change and requires a major version update (we did this going to reek 2). Adding a report format probably also warrents a minor version upgrade.
|
|
4
|
+
* API: We haven't really defined a 'public' API for using Reek programmatically, and we've only just started testing it. So, this is basically a blank slate at the moment. We will work on this as a part of the reek 3 release.
|
|
5
|
+
* List of detected smells: Adding a smell warrants a minor release, removing a smell is a breaking change. This makes sense if you consider that the CLI allows running a single smell detector.
|
|
6
|
+
* Consistency of detected smells: This is very hard to guarantee. If we fix a bug in one of the detectors, some fragrant code may become smelly, or vice versa. Right now we don't bother with this.
|
|
7
|
+
* Smell configuration: The detectors are quite tolerant regarding configuration options that they don't recognize, so we regard any change here as only requiring a minor release.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# YAML Reports
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
`Reek`'s `--yaml` option writes on $stdout a YAML dump of the smells found. Each reported smell has a number of standard fields and a number of fields that are specific to the smell's type. The common fields are as follows:
|
|
6
|
+
|
|
7
|
+
| Field | Type | Value |
|
|
8
|
+
| ---------------|-------------|---------|
|
|
9
|
+
| source | string | The name of the source file containing the smell, or `$stdin` |
|
|
10
|
+
| lines | array | The source file line number(s) that contribute to this smell |
|
|
11
|
+
| context | string | The name of the class, module or method containing the smell |
|
|
12
|
+
| class | string | The class to which this smell belongs |
|
|
13
|
+
| subclass | string | This smell's subclass within the above class |
|
|
14
|
+
| message | string | The message that would have been printed in a standard Reek report |
|
|
15
|
+
| is_active | boolean | `false` if the smell is masked by a config file; `true` otherwise |
|
|
16
|
+
|
|
17
|
+
All of these fields are grouped into hashes `location`, `smell` and `status` (see the examples below).
|
|
18
|
+
|
|
19
|
+
## Examples
|
|
20
|
+
|
|
21
|
+
Duplication:
|
|
22
|
+
|
|
23
|
+
<pre>
|
|
24
|
+
- !ruby/object:Reek::SmellWarning
|
|
25
|
+
location:
|
|
26
|
+
source: spec/samples/masked/dirty.rb
|
|
27
|
+
lines:
|
|
28
|
+
- 5
|
|
29
|
+
- 7
|
|
30
|
+
context: Dirty#a
|
|
31
|
+
smell:
|
|
32
|
+
class: Duplication
|
|
33
|
+
subclass: DuplicateMethodCall
|
|
34
|
+
occurrences: 2
|
|
35
|
+
call: puts(@s.title)
|
|
36
|
+
message: calls puts(@s.title) twice
|
|
37
|
+
status:
|
|
38
|
+
is_active: true
|
|
39
|
+
</pre>
|
|
40
|
+
|
|
41
|
+
[Nested Iterators](Nested-Iterators.md):
|
|
42
|
+
|
|
43
|
+
<pre>
|
|
44
|
+
- !ruby/object:Reek::SmellWarning
|
|
45
|
+
location:
|
|
46
|
+
source: spec/samples/masked/dirty.rb
|
|
47
|
+
lines:
|
|
48
|
+
- 5
|
|
49
|
+
context: Dirty#a
|
|
50
|
+
smell:
|
|
51
|
+
class: NestedIterators
|
|
52
|
+
subclass: ""
|
|
53
|
+
depth: 2
|
|
54
|
+
message: contains iterators nested 2 deep
|
|
55
|
+
status:
|
|
56
|
+
is_active: true
|
|
57
|
+
</pre>
|
|
58
|
+
|
|
59
|
+
[Uncommunicative Method Name](Uncommunicative-Method-Name.md):
|
|
60
|
+
|
|
61
|
+
<pre>
|
|
62
|
+
- !ruby/object:Reek::SmellWarning
|
|
63
|
+
location:
|
|
64
|
+
source: spec/samples/masked/dirty.rb
|
|
65
|
+
lines:
|
|
66
|
+
- 3
|
|
67
|
+
context: Dirty#a
|
|
68
|
+
smell:
|
|
69
|
+
class: UncommunicativeName
|
|
70
|
+
subclass: UncommunicativeMethodName
|
|
71
|
+
method_name: a
|
|
72
|
+
message: has the name 'a'
|
|
73
|
+
status:
|
|
74
|
+
is_active: false
|
|
75
|
+
</pre>
|
|
76
|
+
|
|
77
|
+
[Uncommunicative Variable Name](Uncommunicative-Variable-Name.md):
|
|
78
|
+
|
|
79
|
+
<pre>
|
|
80
|
+
- !ruby/object:Reek::SmellWarning
|
|
81
|
+
location:
|
|
82
|
+
source: spec/samples/masked/dirty.rb
|
|
83
|
+
lines:
|
|
84
|
+
- 5
|
|
85
|
+
context: Dirty#a
|
|
86
|
+
smell:
|
|
87
|
+
class: UncommunicativeName
|
|
88
|
+
subclass: UncommunicativeVariableName
|
|
89
|
+
variable_name: x
|
|
90
|
+
message: has the variable name 'x'
|
|
91
|
+
status:
|
|
92
|
+
is_active: true
|
|
93
|
+
</pre>
|
|
94
|
+
|
|
95
|
+
[Control Couple](Control-Couple.md):
|
|
96
|
+
|
|
97
|
+
<pre>
|
|
98
|
+
- !ruby/object:Reek::SmellWarning
|
|
99
|
+
location:
|
|
100
|
+
source: $stdin
|
|
101
|
+
lines:
|
|
102
|
+
- 2
|
|
103
|
+
context: Turn#fred
|
|
104
|
+
smell:
|
|
105
|
+
class: ControlCouple
|
|
106
|
+
subclass: BooleanParameter
|
|
107
|
+
parameter: arg
|
|
108
|
+
message: has boolean parameter 'arg'
|
|
109
|
+
status:
|
|
110
|
+
is_active: true
|
|
111
|
+
</pre>
|
data/docs/yard_plugin.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'yard'
|
|
2
|
+
|
|
3
|
+
# Template helper to modify processing of links in HTML generated from our
|
|
4
|
+
# markdown files.
|
|
5
|
+
module LocalLinkHelper
|
|
6
|
+
# Rewrites links to (assumed local) markdown files so they're processed as
|
|
7
|
+
# {file: } directives.
|
|
8
|
+
def resolve_links(text)
|
|
9
|
+
text = text.gsub(%r{<a href="([^"]*.md)">([^<]*)</a>}, '{file:\1 \2}')
|
|
10
|
+
super text
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
YARD::Templates::Template.extra_includes << LocalLinkHelper
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
Feature: The Reek
|
|
1
|
+
Feature: The Reek CLI maintains backwards compatibility
|
|
2
2
|
In order to use Reek without fuss
|
|
3
3
|
As a developer
|
|
4
|
-
I want to have a stable
|
|
4
|
+
I want to have a stable basic command line interface
|
|
5
5
|
|
|
6
6
|
Scenario: the demo example reports as expected
|
|
7
|
-
|
|
7
|
+
Given the smelly file 'demo.rb' from the example in the README
|
|
8
|
+
When I run reek demo.rb
|
|
8
9
|
Then the exit status indicates smells
|
|
9
10
|
And it reports:
|
|
10
11
|
"""
|
|
11
|
-
|
|
12
|
+
demo.rb -- 8 warnings:
|
|
12
13
|
[1]:Dirty has no descriptive comment (IrresponsibleModule)
|
|
13
14
|
[3]:Dirty#awful has 4 parameters (LongParameterList)
|
|
14
15
|
[3]:Dirty#awful has boolean parameter 'log' (BooleanParameter)
|
|
16
|
+
[3]:Dirty#awful has the parameter name 'x' (UncommunicativeParameterName)
|
|
15
17
|
[5]:Dirty#awful has the variable name 'w' (UncommunicativeVariableName)
|
|
16
18
|
[3]:Dirty#awful has unused parameter 'log' (UnusedParameters)
|
|
17
19
|
[3]:Dirty#awful has unused parameter 'offset' (UnusedParameters)
|
|
18
|
-
[3]:Dirty#awful has unused parameter 'x' (UnusedParameters)
|
|
19
20
|
[3]:Dirty#awful has unused parameter 'y' (UnusedParameters)
|
|
20
21
|
"""
|
|
@@ -4,15 +4,11 @@ Feature: Smell selection
|
|
|
4
4
|
I want to be able to selectively activate smell detectors
|
|
5
5
|
|
|
6
6
|
Scenario: --smell selects a smell to detect
|
|
7
|
-
|
|
7
|
+
Given a smelly file called 'smelly.rb'
|
|
8
|
+
When I run reek --no-line-numbers --smell UncommunicativeMethodName smelly.rb
|
|
8
9
|
Then the exit status indicates smells
|
|
9
10
|
And it reports:
|
|
10
11
|
"""
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
|
|
14
|
-
spec/samples/two_smelly_files/dirty_two.rb -- 2 warnings:
|
|
15
|
-
Dirty#a calls @s.title 2 times (DuplicateMethodCall)
|
|
16
|
-
Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
|
|
17
|
-
4 total warnings
|
|
12
|
+
smelly.rb -- 1 warning:
|
|
13
|
+
Smelly#m has the name 'm' (UncommunicativeMethodName)
|
|
18
14
|
"""
|