reek 6.0.3 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +31 -26
- data/.rubocop.yml +5 -3
- data/CHANGELOG.md +22 -1
- data/CONTRIBUTING.md +3 -0
- data/Dockerfile +1 -1
- data/Gemfile +7 -7
- data/README.md +1 -1
- data/bin/code_climate_reek +2 -3
- data/lib/reek/ast/ast_node_class_map.rb +1 -1
- data/lib/reek/ast/sexp_extensions/arguments.rb +11 -0
- data/lib/reek/ast/sexp_extensions/case.rb +1 -1
- data/lib/reek/ast/sexp_extensions/if.rb +1 -1
- data/lib/reek/ast/sexp_extensions/send.rb +1 -1
- data/lib/reek/cli/command/todo_list_command.rb +1 -1
- data/lib/reek/cli/options.rb +1 -1
- data/lib/reek/code_comment.rb +22 -17
- data/lib/reek/context_builder.rb +1 -1
- data/lib/reek/rake/task.rb +1 -1
- data/lib/reek/report/code_climate/code_climate_formatter.rb +1 -3
- data/lib/reek/smell_detectors/base_detector.rb +1 -1
- data/lib/reek/smell_warning.rb +1 -1
- data/lib/reek/source/source_locator.rb +1 -3
- data/lib/reek/spec/should_reek_of.rb +6 -4
- data/lib/reek/version.rb +2 -2
- data/reek.gemspec +28 -25
- metadata +7 -225
- data/docs/API.md +0 -174
- data/docs/Attribute.md +0 -39
- data/docs/Basic-Smell-Options.md +0 -85
- data/docs/Boolean-Parameter.md +0 -54
- data/docs/Class-Variable.md +0 -40
- data/docs/Code-Smells.md +0 -39
- data/docs/Command-Line-Options.md +0 -119
- data/docs/Control-Couple.md +0 -26
- data/docs/Control-Parameter.md +0 -32
- data/docs/Data-Clump.md +0 -46
- data/docs/Duplicate-Method-Call.md +0 -264
- data/docs/Feature-Envy.md +0 -93
- data/docs/How-To-Write-New-Detectors.md +0 -132
- data/docs/How-reek-works-internally.md +0 -114
- data/docs/Instance-Variable-Assumption.md +0 -163
- data/docs/Irresponsible-Module.md +0 -47
- data/docs/Large-Class.md +0 -16
- data/docs/Long-Parameter-List.md +0 -39
- data/docs/Long-Yield-List.md +0 -37
- data/docs/Manual-Dispatch.md +0 -30
- data/docs/Missing-Safe-Method.md +0 -92
- data/docs/Module-Initialize.md +0 -62
- data/docs/Nested-Iterators.md +0 -59
- data/docs/Nil-Check.md +0 -47
- data/docs/RSpec-matchers.md +0 -129
- data/docs/Rake-Task.md +0 -66
- data/docs/Reek-4-to-Reek-5-migration.md +0 -188
- data/docs/Reek-Driven-Development.md +0 -46
- data/docs/Repeated-Conditional.md +0 -47
- data/docs/Simulated-Polymorphism.md +0 -16
- data/docs/Smell-Suppression.md +0 -96
- data/docs/Style-Guide.md +0 -19
- data/docs/Subclassed-From-Core-Class.md +0 -79
- data/docs/Too-Many-Constants.md +0 -37
- data/docs/Too-Many-Instance-Variables.md +0 -43
- data/docs/Too-Many-Methods.md +0 -56
- data/docs/Too-Many-Statements.md +0 -54
- data/docs/Uncommunicative-Method-Name.md +0 -94
- data/docs/Uncommunicative-Module-Name.md +0 -92
- data/docs/Uncommunicative-Name.md +0 -18
- data/docs/Uncommunicative-Parameter-Name.md +0 -90
- data/docs/Uncommunicative-Variable-Name.md +0 -96
- data/docs/Unused-Parameters.md +0 -28
- data/docs/Unused-Private-Method.md +0 -101
- data/docs/Utility-Function.md +0 -56
- data/docs/Versioning-Policy.md +0 -7
- data/docs/YAML-Reports.md +0 -93
- data/docs/defaults.reek.yml +0 -129
- data/docs/templates/default/docstring/html/public_api_marker.erb +0 -3
- data/docs/templates/default/docstring/setup.rb +0 -35
- data/docs/templates/default/fulldoc/html/css/common.css +0 -1
- data/docs/yard_plugin.rb +0 -17
- data/features/command_line_interface/basic_usage.feature +0 -15
- data/features/command_line_interface/options.feature +0 -123
- data/features/command_line_interface/show_progress.feature +0 -33
- data/features/command_line_interface/smell_selection.feature +0 -15
- data/features/command_line_interface/smells_count.feature +0 -38
- data/features/command_line_interface/stdin.feature +0 -65
- data/features/configuration_files/accept_setting.feature +0 -87
- data/features/configuration_files/directory_specific_directives.feature +0 -274
- data/features/configuration_files/exclude_directives.feature +0 -35
- data/features/configuration_files/exclude_paths_directives.feature +0 -42
- data/features/configuration_files/masking_smells.feature +0 -94
- data/features/configuration_files/mix_accept_reject_setting.feature +0 -84
- data/features/configuration_files/reject_setting.feature +0 -89
- data/features/configuration_files/schema_validation.feature +0 -59
- data/features/configuration_files/show_configuration_file.feature +0 -44
- data/features/configuration_files/unused_private_method.feature +0 -68
- data/features/configuration_loading.feature +0 -91
- data/features/configuration_via_source_comments/erroneous_source_comments.feature +0 -68
- data/features/configuration_via_source_comments/well_formed_source_comments.feature +0 -116
- data/features/locales.feature +0 -32
- data/features/programmatic_access.feature +0 -41
- data/features/rake_task/rake_task.feature +0 -138
- data/features/reports/codeclimate.feature +0 -59
- data/features/reports/json.feature +0 -59
- data/features/reports/reports.feature +0 -219
- data/features/reports/yaml.feature +0 -52
- data/features/rspec_matcher.feature +0 -41
- data/features/samples.feature +0 -305
- data/features/step_definitions/.rubocop.yml +0 -5
- data/features/step_definitions/reek_steps.rb +0 -102
- data/features/step_definitions/sample_file_steps.rb +0 -63
- data/features/support/env.rb +0 -33
- data/features/todo_list.feature +0 -108
- data/samples/checkstyle.xml +0 -7
- data/samples/clean_source/clean.rb +0 -6
- data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +0 -29
- data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +0 -30
- data/samples/configuration/corrupt.reek +0 -1
- data/samples/configuration/empty.reek +0 -0
- data/samples/configuration/full_configuration.reek +0 -13
- data/samples/configuration/full_mask.reek +0 -6
- data/samples/configuration/home/home.reek.yml +0 -4
- data/samples/configuration/partial_mask.reek +0 -4
- data/samples/configuration/regular_configuration/.reek.yml +0 -4
- data/samples/configuration/regular_configuration/empty_sub_directory/.gitignore +0 -0
- data/samples/configuration/with_excluded_paths.reek +0 -5
- data/samples/no_config_file/.keep +0 -0
- data/samples/paths.rb +0 -5
- data/samples/smelly_source/inline.rb +0 -704
- data/samples/smelly_source/optparse.rb +0 -1788
- data/samples/smelly_source/redcloth.rb +0 -1130
- data/samples/smelly_source/ruby.rb +0 -368
- data/samples/smelly_source/smelly.rb +0 -7
- data/samples/source_with_exclude_paths/ignore_me/uncommunicative_method_name.rb +0 -5
- data/samples/source_with_exclude_paths/nested/ignore_me_as_well/irresponsible_module.rb +0 -2
- data/samples/source_with_exclude_paths/nested/uncommunicative_parameter_name.rb +0 -6
- data/samples/source_with_exclude_paths/nested/uncommunicative_variable_name.rb +0 -6
- data/samples/source_with_hidden_directories/.hidden/hidden.rb +0 -1
- data/samples/source_with_hidden_directories/not_hidden.rb +0 -1
- data/samples/source_with_non_ruby_files/gibberish +0 -1
- data/samples/source_with_non_ruby_files/python_source.py +0 -1
- data/samples/source_with_non_ruby_files/ruby.rb +0 -6
- data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +0 -15
- data/spec/quality/documentation_spec.rb +0 -41
- data/spec/quality/reek_source_spec.rb +0 -11
- data/spec/reek/ast/node_spec.rb +0 -211
- data/spec/reek/ast/object_refs_spec.rb +0 -83
- data/spec/reek/ast/reference_collector_spec.rb +0 -47
- data/spec/reek/ast/sexp_extensions_spec.rb +0 -498
- data/spec/reek/cli/application_spec.rb +0 -168
- data/spec/reek/cli/command/report_command_spec.rb +0 -44
- data/spec/reek/cli/command/todo_list_command_spec.rb +0 -86
- data/spec/reek/cli/options_spec.rb +0 -51
- data/spec/reek/cli/silencer_spec.rb +0 -28
- data/spec/reek/code_comment_spec.rb +0 -184
- data/spec/reek/configuration/app_configuration_spec.rb +0 -195
- data/spec/reek/configuration/configuration_file_finder_spec.rb +0 -230
- data/spec/reek/configuration/default_directive_spec.rb +0 -13
- data/spec/reek/configuration/directory_directives_spec.rb +0 -122
- data/spec/reek/configuration/excluded_paths_spec.rb +0 -25
- data/spec/reek/configuration/rake_task_converter_spec.rb +0 -33
- data/spec/reek/configuration/schema_validator_spec.rb +0 -165
- data/spec/reek/context/code_context_spec.rb +0 -192
- data/spec/reek/context/ghost_context_spec.rb +0 -60
- data/spec/reek/context/method_context_spec.rb +0 -72
- data/spec/reek/context/module_context_spec.rb +0 -55
- data/spec/reek/context/root_context_spec.rb +0 -12
- data/spec/reek/context/statement_counter_spec.rb +0 -24
- data/spec/reek/context_builder_spec.rb +0 -457
- data/spec/reek/detector_repository_spec.rb +0 -22
- data/spec/reek/documentation_link_spec.rb +0 -20
- data/spec/reek/errors/base_error_spec.rb +0 -13
- data/spec/reek/examiner_spec.rb +0 -309
- data/spec/reek/logging_error_handler_spec.rb +0 -24
- data/spec/reek/rake/task_spec.rb +0 -56
- data/spec/reek/report/code_climate/code_climate_configuration_spec.rb +0 -22
- data/spec/reek/report/code_climate/code_climate_fingerprint_spec.rb +0 -126
- data/spec/reek/report/code_climate/code_climate_formatter_spec.rb +0 -51
- data/spec/reek/report/code_climate/code_climate_report_spec.rb +0 -56
- data/spec/reek/report/html_report_spec.rb +0 -19
- data/spec/reek/report/json_report_spec.rb +0 -58
- data/spec/reek/report/location_formatter_spec.rb +0 -32
- data/spec/reek/report/progress_formatter_spec.rb +0 -68
- data/spec/reek/report/text_report_spec.rb +0 -89
- data/spec/reek/report/xml_report_spec.rb +0 -24
- data/spec/reek/report/yaml_report_spec.rb +0 -55
- data/spec/reek/report_spec.rb +0 -28
- data/spec/reek/smell_configuration_spec.rb +0 -56
- data/spec/reek/smell_detectors/attribute_spec.rb +0 -197
- data/spec/reek/smell_detectors/base_detector_spec.rb +0 -50
- data/spec/reek/smell_detectors/boolean_parameter_spec.rb +0 -93
- data/spec/reek/smell_detectors/class_variable_spec.rb +0 -106
- data/spec/reek/smell_detectors/control_parameter_spec.rb +0 -300
- data/spec/reek/smell_detectors/data_clump_spec.rb +0 -134
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +0 -211
- data/spec/reek/smell_detectors/feature_envy_spec.rb +0 -295
- data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +0 -96
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +0 -226
- data/spec/reek/smell_detectors/long_parameter_list_spec.rb +0 -61
- data/spec/reek/smell_detectors/long_yield_list_spec.rb +0 -49
- data/spec/reek/smell_detectors/manual_dispatch_spec.rb +0 -75
- data/spec/reek/smell_detectors/missing_safe_method_spec.rb +0 -68
- data/spec/reek/smell_detectors/module_initialize_spec.rb +0 -77
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +0 -333
- data/spec/reek/smell_detectors/nil_check_spec.rb +0 -100
- data/spec/reek/smell_detectors/repeated_conditional_spec.rb +0 -100
- data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +0 -77
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +0 -144
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +0 -132
- data/spec/reek/smell_detectors/too_many_methods_spec.rb +0 -54
- data/spec/reek/smell_detectors/too_many_statements_spec.rb +0 -90
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +0 -78
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +0 -78
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +0 -147
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +0 -201
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +0 -114
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +0 -205
- data/spec/reek/smell_detectors/utility_function_spec.rb +0 -309
- data/spec/reek/smell_warning_spec.rb +0 -137
- data/spec/reek/source/source_code_spec.rb +0 -79
- data/spec/reek/source/source_locator_spec.rb +0 -166
- data/spec/reek/spec/should_reek_of_spec.rb +0 -153
- data/spec/reek/spec/should_reek_only_of_spec.rb +0 -91
- data/spec/reek/spec/should_reek_spec.rb +0 -52
- data/spec/reek/spec/smell_matcher_spec.rb +0 -87
- data/spec/reek/tree_dresser_spec.rb +0 -46
- data/spec/spec_helper.rb +0 -110
- data/tasks/configuration.rake +0 -18
- data/tasks/console.rake +0 -5
- data/tasks/reek.rake +0 -6
- data/tasks/rubocop.rake +0 -11
- data/tasks/test.rake +0 -32
data/docs/Module-Initialize.md
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# Module Initialize
|
2
|
-
|
3
|
-
## Introduction
|
4
|
-
|
5
|
-
A module is usually a mixin, so when an `#initialize` method is present it is
|
6
|
-
hard to tell initialization order and parameters so having `#initialize`
|
7
|
-
in a module is usually a bad idea.
|
8
|
-
|
9
|
-
## Example
|
10
|
-
|
11
|
-
The `Foo` module below contains a method `initialize`. Although class `B` inherits from `A`, the inclusion of `Foo` stops `A#initialize` from being called.
|
12
|
-
|
13
|
-
```Ruby
|
14
|
-
class A
|
15
|
-
def initialize(a)
|
16
|
-
@a = a
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module Foo
|
21
|
-
def initialize(foo)
|
22
|
-
@foo = foo
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class B < A
|
27
|
-
include Foo
|
28
|
-
|
29
|
-
def initialize(b)
|
30
|
-
super('bar')
|
31
|
-
@b = b
|
32
|
-
end
|
33
|
-
end
|
34
|
-
```
|
35
|
-
|
36
|
-
A simple solution is to rename `Foo#initialize` and call that method by name:
|
37
|
-
|
38
|
-
```Ruby
|
39
|
-
module Foo
|
40
|
-
def setup_foo_module(foo)
|
41
|
-
@foo = foo
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class B < A
|
46
|
-
include Foo
|
47
|
-
|
48
|
-
def initialize(b)
|
49
|
-
super 'bar'
|
50
|
-
setup_foo_module('foo')
|
51
|
-
@b = b
|
52
|
-
end
|
53
|
-
end
|
54
|
-
```
|
55
|
-
|
56
|
-
## Current Support in Reek
|
57
|
-
|
58
|
-
Reek warns about module initialize when an instance method named `initialize` is present in a module.
|
59
|
-
|
60
|
-
## Configuration
|
61
|
-
|
62
|
-
Module Initialize supports the [Basic Smell Options](Basic-Smell-Options.md).
|
data/docs/Nested-Iterators.md
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# Nested Iterators
|
2
|
-
|
3
|
-
## Introduction
|
4
|
-
|
5
|
-
A _Nested Iterator_ occurs when a block contains another block.
|
6
|
-
|
7
|
-
## Example
|
8
|
-
|
9
|
-
Given
|
10
|
-
|
11
|
-
```Ruby
|
12
|
-
class Duck
|
13
|
-
class << self
|
14
|
-
def duck_names
|
15
|
-
%i!tick trick track!.each do |surname|
|
16
|
-
%i!duck!.each do |last_name|
|
17
|
-
puts "full name is #{surname} #{last_name}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
```
|
24
|
-
|
25
|
-
Reek would report the following warning:
|
26
|
-
|
27
|
-
```
|
28
|
-
test.rb -- 1 warning:
|
29
|
-
[5]:Duck#duck_names contains iterators nested 2 deep (NestedIterators)
|
30
|
-
```
|
31
|
-
|
32
|
-
## Current Support in Reek
|
33
|
-
|
34
|
-
_Nested Iterators_ reports failing methods only once.
|
35
|
-
`Object#tap` is ignored by default and thus does not count as iterator.
|
36
|
-
Furthermore iterators without block arguments are not counted, e.g.:
|
37
|
-
|
38
|
-
|
39
|
-
```Ruby
|
40
|
-
def foo
|
41
|
-
before do
|
42
|
-
item.each do |part|
|
43
|
-
puts part
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
```
|
48
|
-
|
49
|
-
would not smell of NestedIterators (given a maximum allowed nesting of 1) since the
|
50
|
-
`before` would not be counted (because it doesn't pass any arguments to the block).
|
51
|
-
|
52
|
-
## Configuration
|
53
|
-
|
54
|
-
_Nested Iterators_ offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
55
|
-
|
56
|
-
| Option | Value | Effect |
|
57
|
-
| ----------------------|---------|---------|
|
58
|
-
| `max_allowed_nesting` | integer | The maximum depth of nested iterators. Defaults to 1 |
|
59
|
-
| `ignore_iterators` | Array | List of iterators to be excluded from the smell check. Includes only `tap` at the moment|
|
data/docs/Nil-Check.md
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
# Nil Check
|
2
|
-
|
3
|
-
## Introduction
|
4
|
-
|
5
|
-
A _Nil Check_ is a type check. Failures of _Nil Check_ violate the
|
6
|
-
["tell, don't ask"](http://robots.thoughtbot.com/tell-dont-ask) principle.
|
7
|
-
Additionally to that, type checks often mask bigger problems in your source
|
8
|
-
code like not using OOP and / or polymorphism when you should.
|
9
|
-
|
10
|
-
The _Nil Check_ code smell is a case of [Simulated Polymorphism](Simulated-Polymorphism.md).
|
11
|
-
|
12
|
-
## Example
|
13
|
-
|
14
|
-
Given
|
15
|
-
|
16
|
-
```Ruby
|
17
|
-
class Klass
|
18
|
-
def nil_checker(argument)
|
19
|
-
if argument.nil?
|
20
|
-
puts "argument is nil!"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
```
|
25
|
-
|
26
|
-
Reek would emit the following warning:
|
27
|
-
|
28
|
-
```
|
29
|
-
test.rb -- 1 warning:
|
30
|
-
[3]:Klass#nil_checker performs a nil-check. (NilCheck)
|
31
|
-
```
|
32
|
-
|
33
|
-
## Current Support in Reek
|
34
|
-
|
35
|
-
_Nil Check_ reports use of
|
36
|
-
|
37
|
-
* <code>.nil?</code> method
|
38
|
-
* <code>==</code> and <code>===</code> operators when checking vs. <code>nil</code>
|
39
|
-
* case statements that use syntax like <code>when nil</code>
|
40
|
-
|
41
|
-
_Nil Check_ allows use of
|
42
|
-
|
43
|
-
* the safe navigation operator like `foo&.bar`
|
44
|
-
|
45
|
-
## Configuration
|
46
|
-
|
47
|
-
_Nil Check_ offers the [Basic Smell Options](Basic-Smell-Options.md).
|
data/docs/RSpec-matchers.md
DELETED
@@ -1,129 +0,0 @@
|
|
1
|
-
# RSpec matchers
|
2
|
-
|
3
|
-
## Introduction
|
4
|
-
|
5
|
-
Reek offers matchers for RSpec you can easily include into your project.
|
6
|
-
|
7
|
-
There are 3 matchers available:
|
8
|
-
|
9
|
-
- `reek`
|
10
|
-
- `reek_of`
|
11
|
-
- `reek_only_of`
|
12
|
-
|
13
|
-
## Quickstart
|
14
|
-
|
15
|
-
Let's install the dependencies:
|
16
|
-
|
17
|
-
```
|
18
|
-
gem install reek
|
19
|
-
gem install rspec
|
20
|
-
```
|
21
|
-
|
22
|
-
And then use it like that in your spec file:
|
23
|
-
|
24
|
-
```Ruby
|
25
|
-
require 'reek'
|
26
|
-
require 'reek/spec'
|
27
|
-
require 'rspec'
|
28
|
-
|
29
|
-
RSpec.describe 'Reek Integration' do
|
30
|
-
it 'works with Reek' do
|
31
|
-
smelly_class = 'class C; def m; end; end'
|
32
|
-
expect(smelly_class).not_to reek
|
33
|
-
end
|
34
|
-
end
|
35
|
-
```
|
36
|
-
|
37
|
-
Running this via
|
38
|
-
|
39
|
-
```
|
40
|
-
rspec reek-integration-spec.rb
|
41
|
-
```
|
42
|
-
|
43
|
-
would give you:
|
44
|
-
|
45
|
-
```
|
46
|
-
Failures:
|
47
|
-
|
48
|
-
1) Reek Integration works with Reek
|
49
|
-
Failure/Error: expect(smelly_class).not_to reek
|
50
|
-
Expected no smells, but got:
|
51
|
-
C has no descriptive comment (IrresponsibleModule)
|
52
|
-
C has the name 'C' (UncommunicativeModuleName)
|
53
|
-
C#m has the name 'm' (UncommunicativeMethodName)
|
54
|
-
# ./reek-integration-spec.rb:8:in `block (2 levels) in <top (required)>'
|
55
|
-
|
56
|
-
Finished in 0.00284 seconds (files took 0.28815 seconds to load)
|
57
|
-
1 example, 1 failure
|
58
|
-
|
59
|
-
Failed examples:
|
60
|
-
|
61
|
-
rspec ./reek-integration-spec.rb:6 # Reek Integration works with Reek
|
62
|
-
```
|
63
|
-
|
64
|
-
## The matchers explained
|
65
|
-
|
66
|
-
### `reek`
|
67
|
-
|
68
|
-
A very generic matcher that basically just tells you if something reeks, but
|
69
|
-
not after what exactly.
|
70
|
-
See the "Quickstart" example from above.
|
71
|
-
|
72
|
-
### `reek_of`
|
73
|
-
|
74
|
-
Checks the target source code for instances of "smell type"
|
75
|
-
and returns true only if it can find one of them that matches.
|
76
|
-
|
77
|
-
You can pass the smell type you want to check for as String or as Symbol:
|
78
|
-
|
79
|
-
- `:UtilityFunction`
|
80
|
-
- `"UtilityFunction"`
|
81
|
-
|
82
|
-
It is recommended to pass this as a symbol like `:UtilityFunction`. However we
|
83
|
-
don't enforce this.
|
84
|
-
|
85
|
-
Additionally you can be more specific and pass in "smell_details" you want to
|
86
|
-
check for as well e.g. "name" or "count" (see the examples below). The
|
87
|
-
parameters you can check for are depending on the smell you are checking for.
|
88
|
-
For instance "count" doesn't make sense everywhere whereas "name" does in most
|
89
|
-
cases. If you pass in a parameter that doesn't exist (e.g. you make a typo like
|
90
|
-
"namme") Reek will raise an ArgumentError to give you a hint that you passed
|
91
|
-
something that doesn't make much sense.
|
92
|
-
|
93
|
-
So in a nutshell `reek_of` takes the following two arguments:
|
94
|
-
|
95
|
-
- `smell_type` - The "smell type" we check for.
|
96
|
-
- `smells_details` - A hash containing "smell warning" parameters
|
97
|
-
|
98
|
-
**Examples**
|
99
|
-
|
100
|
-
Without smell_details:
|
101
|
-
|
102
|
-
```Ruby
|
103
|
-
reek_of(:FeatureEnvy)
|
104
|
-
reek_of(:UtilityFunction)
|
105
|
-
```
|
106
|
-
|
107
|
-
With smell_details:
|
108
|
-
|
109
|
-
```Ruby
|
110
|
-
reek_of(:UncommunicativeParameterName, name: 'x2')
|
111
|
-
reek_of(:DataClump, count: 3)
|
112
|
-
```
|
113
|
-
|
114
|
-
**Examples from a real spec**
|
115
|
-
|
116
|
-
```Ruby
|
117
|
-
expect(src).to reek_of(:DuplicateMethodCall, name: '@other.thing')
|
118
|
-
```
|
119
|
-
|
120
|
-
### reek_only_of
|
121
|
-
|
122
|
-
See the documentaton for `reek_of`.
|
123
|
-
|
124
|
-
**Notable differences to `reek_of`:**
|
125
|
-
|
126
|
-
1. `reek_of` doesn't mind if there are other smells of a different type.
|
127
|
-
"reek_only_of" will fail in that case.
|
128
|
-
|
129
|
-
2. `reek_only_of` doesn't support the additional smell_details hash.
|
data/docs/Rake-Task.md
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
# Rake Task
|
2
|
-
|
3
|
-
## Introduction
|
4
|
-
|
5
|
-
Reek provides a Rake task that runs Reek on a set of source files. In its most simple form you just include something like that in your Rakefile:
|
6
|
-
|
7
|
-
```Ruby
|
8
|
-
require 'reek/rake/task'
|
9
|
-
|
10
|
-
Reek::Rake::Task.new do |t|
|
11
|
-
t.fail_on_error = false
|
12
|
-
end
|
13
|
-
```
|
14
|
-
|
15
|
-
In its most simple form, that's it.
|
16
|
-
|
17
|
-
When you now run:
|
18
|
-
|
19
|
-
```Bash
|
20
|
-
rake -T
|
21
|
-
```
|
22
|
-
|
23
|
-
you should see
|
24
|
-
|
25
|
-
```Bash
|
26
|
-
rake reek # Check for code smells
|
27
|
-
```
|
28
|
-
|
29
|
-
## Configuration via task
|
30
|
-
|
31
|
-
An more sophisticated rake task that would make use of all available configuration options could look like this:
|
32
|
-
|
33
|
-
```Ruby
|
34
|
-
Reek::Rake::Task.new do |t|
|
35
|
-
t.name = 'custom_rake' # Whatever name you want. Defaults to "reek".
|
36
|
-
t.config_file = 'config/.reek.yml' # Defaults to nothing.
|
37
|
-
t.source_files = 'vendor/**/*.rb' # Glob pattern to match source files. Defaults to lib/**/*.rb
|
38
|
-
t.reek_opts = '-U' # Defaults to ''. You can pass all the options here in that are shown by "reek -h"
|
39
|
-
t.fail_on_error = false # Defaults to true
|
40
|
-
t.verbose = true # Defaults to false
|
41
|
-
end
|
42
|
-
```
|
43
|
-
|
44
|
-
Alternatively, you can create your own [Rake::FileList](http://rake.rubyforge.org/classes/Rake/FileList.html) and use that for `source_files`:
|
45
|
-
|
46
|
-
```Ruby
|
47
|
-
Reek::Rake::Task.new do |t|
|
48
|
-
t.source_files = FileList['lib/**/*.rb'].exclude('lib/templates/**/*.rb')
|
49
|
-
end
|
50
|
-
```
|
51
|
-
|
52
|
-
## Configuration via environment variables
|
53
|
-
|
54
|
-
You can overwrite the following attributes by environment variables:
|
55
|
-
|
56
|
-
- "reek_opts" by using REEK_OPTS
|
57
|
-
- "config_file" by using REEK_CFG
|
58
|
-
- "source_files" by using REEK_SRC
|
59
|
-
|
60
|
-
An example rake call using environment variables could look like this:
|
61
|
-
|
62
|
-
```Bash
|
63
|
-
REEK_CFG="config/custom.reek" REEK_OPTS="-s" rake reek
|
64
|
-
```
|
65
|
-
|
66
|
-
See also: [Reek-Driven-Development](Reek-Driven-Development.md)
|
@@ -1,188 +0,0 @@
|
|
1
|
-
## Reek 4 to Reek 5 migration
|
2
|
-
|
3
|
-
### Schema validation
|
4
|
-
|
5
|
-
Reek now uses a schema to validate your configuration against on start up and will faily loudly in
|
6
|
-
case you misspelled an option or used the wrong data type for a value like this:
|
7
|
-
|
8
|
-
```
|
9
|
-
Error: We found some problems with your configuration file: [/detectors/DetectorWithTypo] key 'DetectorWithTypo:' is undefined.
|
10
|
-
```
|
11
|
-
|
12
|
-
Obviously this might affect existing configuration files that until now contained an error nobody noticed.
|
13
|
-
|
14
|
-
### Scoping detectors under `detectors`
|
15
|
-
|
16
|
-
In Reek 4 you could just configure your detectors on top level like this:
|
17
|
-
|
18
|
-
```yaml
|
19
|
-
UncommunicativeMethodName:
|
20
|
-
accept:
|
21
|
-
- foobar
|
22
|
-
UnusedPrivateMethod:
|
23
|
-
exclude:
|
24
|
-
- app/controllers
|
25
|
-
```
|
26
|
-
|
27
|
-
In Reek 5 you have to scope your detector configurations under the `detectors` key:
|
28
|
-
|
29
|
-
```yaml
|
30
|
-
detectors:
|
31
|
-
UncommunicativeMethodName:
|
32
|
-
accept:
|
33
|
-
- foobar
|
34
|
-
UnusedPrivateMethod:
|
35
|
-
exclude:
|
36
|
-
- app/controllers
|
37
|
-
```
|
38
|
-
|
39
|
-
### Move directory directives under a special key
|
40
|
-
|
41
|
-
In Reek 4 you could apply directory specific directives like this:
|
42
|
-
|
43
|
-
```Yaml
|
44
|
-
---
|
45
|
-
"web_app/app/controllers":
|
46
|
-
NestedIterators:
|
47
|
-
enabled: false
|
48
|
-
"web_app/app/helpers":
|
49
|
-
UtilityFunction:
|
50
|
-
enabled: false
|
51
|
-
```
|
52
|
-
|
53
|
-
which was nice and easy but also quite messy. With Reek 5 you'll have to scope this under a `directories`
|
54
|
-
key like this:
|
55
|
-
|
56
|
-
```Yaml
|
57
|
-
---
|
58
|
-
directories:
|
59
|
-
"web_app/app/controllers":
|
60
|
-
NestedIterators:
|
61
|
-
enabled: false
|
62
|
-
"web_app/app/helpers":
|
63
|
-
UtilityFunction:
|
64
|
-
enabled: false
|
65
|
-
```
|
66
|
-
|
67
|
-
### No more regular expressions in Reeks configuration
|
68
|
-
|
69
|
-
In Reek 4 you could pass regular expressions to the `accept` or `reject` settings of
|
70
|
-
|
71
|
-
* [Uncommunicative Method Name](Uncommunicative-Method-Name.md)
|
72
|
-
* [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
|
73
|
-
* [Uncommunicative Parameter Name](Uncommunicative-Parameter-Name.md)
|
74
|
-
* [Uncommunicative Variable Name](Uncommunicative-Variable-Name.md)
|
75
|
-
|
76
|
-
and to the `exclude` settings which are part of our [Basic Smell Options](docs/Basic-Smell-Options.md).
|
77
|
-
|
78
|
-
This means that this configuration was perfectly valid:
|
79
|
-
|
80
|
-
```yaml
|
81
|
-
detectors:
|
82
|
-
UncommunicativeMethodName:
|
83
|
-
accept:
|
84
|
-
- !ruby/regexp /foobar/
|
85
|
-
UnusedPrivateMethod:
|
86
|
-
exclude:
|
87
|
-
- !ruby/regexp /i am(.*)unused/
|
88
|
-
```
|
89
|
-
|
90
|
-
Support for this has been scrapped with Reek 5 to make the Reek configuration more yaml standard compliant.
|
91
|
-
You can still pass in regexes, you just have to wrap them into a string using a forward slash at the
|
92
|
-
beginning and at the end of the string like this:
|
93
|
-
|
94
|
-
```Yaml
|
95
|
-
---
|
96
|
-
UncommunicativeMethodName:
|
97
|
-
accept:
|
98
|
-
- "/^foobar$/"
|
99
|
-
UnusedPrivateMethod:
|
100
|
-
exclude:
|
101
|
-
- "/i am(.*)unused/"
|
102
|
-
```
|
103
|
-
|
104
|
-
Everything within the forward slashes will be loaded as a regex.
|
105
|
-
|
106
|
-
### No more single item shortcuts for list items
|
107
|
-
|
108
|
-
You cant use a configuration option that is supposed to be a list with a single element like this anymore:
|
109
|
-
|
110
|
-
```Yaml
|
111
|
-
---
|
112
|
-
UncommunicativeMethodName:
|
113
|
-
accept: foobar
|
114
|
-
UnusedPrivateMethod:
|
115
|
-
exclude: omg
|
116
|
-
```
|
117
|
-
|
118
|
-
You'll have to use a proper list here like this:
|
119
|
-
|
120
|
-
```Yaml
|
121
|
-
---
|
122
|
-
UncommunicativeMethodName:
|
123
|
-
accept:
|
124
|
-
- foobar
|
125
|
-
UnusedPrivateMethod:
|
126
|
-
exclude:
|
127
|
-
- omg
|
128
|
-
```
|
129
|
-
|
130
|
-
## Failing on syntax errors in source files
|
131
|
-
|
132
|
-
Previously Reek would just continue on syntax errors in source files which might have been convenient but
|
133
|
-
not necessarily fitting for a tool that's all about code quality. With Reek 5, Reek will fail hard on
|
134
|
-
invalid source files.
|
135
|
-
|
136
|
-
### API changes
|
137
|
-
|
138
|
-
This is something that will only affect very advanced users. In case you have no idea what this might be about
|
139
|
-
you can just skip it or check out our [Developer API](docs/API.md).
|
140
|
-
|
141
|
-
#### Allow only detector names in configuration hash
|
142
|
-
|
143
|
-
In Reek 4 you could build your configuration like this:
|
144
|
-
|
145
|
-
```ruby
|
146
|
-
config_hash = { Reek::SmellDetectors::IrresponsibleModule => { 'enabled' => false } }
|
147
|
-
```
|
148
|
-
|
149
|
-
or like this:
|
150
|
-
|
151
|
-
```ruby
|
152
|
-
config_hash = { 'IrresponsibleModule' => { 'enabled' => false } }
|
153
|
-
```
|
154
|
-
|
155
|
-
Starting with Reek 5, the first way is not working anymore and the latter one is what you'll have to use.
|
156
|
-
|
157
|
-
#### Do not accept a class as parameter for reek_of
|
158
|
-
|
159
|
-
In the same vein as the change above you also can't use fully qualified detector names like this:
|
160
|
-
|
161
|
-
```Ruby
|
162
|
-
reek_of(Reek::SmellDetectors::DuplicateMethodCall)
|
163
|
-
```
|
164
|
-
|
165
|
-
The only supported way now is either as symbol or string:
|
166
|
-
|
167
|
-
```Ruby
|
168
|
-
reek_of(:DuplicateMethodCall)
|
169
|
-
reek_of('DuplicateMethodCall')
|
170
|
-
```
|
171
|
-
|
172
|
-
## Smaller changes
|
173
|
-
|
174
|
-
* `PrimaDonnaMethod` has been given the better name `MissingSafeMethod`
|
175
|
-
* `wiki-links` flag has been renamed to `documentation` flag
|
176
|
-
* Reek assumes the default configuration file to be named ".reek.yml" and will ignore all other files. You can
|
177
|
-
still use any name you want though by passing in a name via the `-c` flag
|
178
|
-
* We have dropped the legacy code comment separator `:` at the end of a detector name. Before this release,
|
179
|
-
to configure a smell detector via comment, you had to end with a colon after the detector name.
|
180
|
-
This syntax is disallowed with Reek 5 - now you have to drop the `:` at the end, like this:
|
181
|
-
|
182
|
-
```diff
|
183
|
-
-# :reek:UnusedPrivateMethod: { exclude: [ bravo ] }
|
184
|
-
+# :reek:UnusedPrivateMethod { exclude: [ bravo ] }
|
185
|
-
```
|
186
|
-
|
187
|
-
* We have dropped support for Ruby 2.1 and 2.2 since they are officially not supported by the Ruby core team anymore
|
188
|
-
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# Reek-Driven Development
|
2
|
-
|
3
|
-
One way to drive quality into your code from the very beginning of a project is to run Reek as a part of your testing process.
|
4
|
-
|
5
|
-
## Rake: `Reek::Rake::Task`
|
6
|
-
|
7
|
-
You can add a [Rake Task] to your Rakefile, which will run Reek on all your source files.
|
8
|
-
|
9
|
-
```Ruby
|
10
|
-
require 'reek/rake/task'
|
11
|
-
|
12
|
-
Reek::Rake::Task.new do |t|
|
13
|
-
t.fail_on_error = true
|
14
|
-
t.verbose = false
|
15
|
-
t.source_files = 'lib/**/*.rb'
|
16
|
-
end
|
17
|
-
```
|
18
|
-
|
19
|
-
Now, `rake reek` will run Reek on your source code. And, in this case, it fails if it finds any smells.
|
20
|
-
|
21
|
-
For more detailed information about Reek's integration with Rake, see [Rake Task].
|
22
|
-
|
23
|
-
[Rake Task]: Rake-Task.md
|
24
|
-
|
25
|
-
## RSpec: `reek/spec`
|
26
|
-
|
27
|
-
You can add Reek expectations directly into your RSpec specs.
|
28
|
-
|
29
|
-
This example is from Reek's own source code:
|
30
|
-
|
31
|
-
```Ruby
|
32
|
-
require 'reek/spec'
|
33
|
-
|
34
|
-
it 'contains no code smells' do
|
35
|
-
Pathname.glob('lib/**/*.rb').each do |file|
|
36
|
-
expect(file).not_to reek
|
37
|
-
end
|
38
|
-
end
|
39
|
-
```
|
40
|
-
|
41
|
-
By requiring [`reek/spec`] you gain access to the `reek` matcher.
|
42
|
-
|
43
|
-
The `reek` matcher returns true if and only if Reek finds smells in your code. If the test fails, the matcher produces an error message that includes details of all the smells it found.
|
44
|
-
|
45
|
-
[`reek/spec`]: ../lib/reek/spec.rb
|
46
|
-
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# Repeated Conditional
|
2
|
-
|
3
|
-
## Introduction
|
4
|
-
|
5
|
-
_Repeated Conditional_ is a case of
|
6
|
-
[Simulated Polymorphism](Simulated-Polymorphism.md). Basically it means you are
|
7
|
-
checking the same value throughout a single class and take decisions based on
|
8
|
-
this.
|
9
|
-
|
10
|
-
## Example
|
11
|
-
|
12
|
-
Given
|
13
|
-
|
14
|
-
```Ruby
|
15
|
-
class RepeatedConditionals
|
16
|
-
attr_accessor :switch
|
17
|
-
|
18
|
-
def repeat_1
|
19
|
-
puts "Repeat 1!" if switch
|
20
|
-
end
|
21
|
-
|
22
|
-
def repeat_2
|
23
|
-
puts "Repeat 2!" if switch
|
24
|
-
end
|
25
|
-
|
26
|
-
def repeat_3
|
27
|
-
puts "Repeat 3!" if switch
|
28
|
-
end
|
29
|
-
end
|
30
|
-
```
|
31
|
-
|
32
|
-
Reek would emit the following warning:
|
33
|
-
|
34
|
-
```
|
35
|
-
test.rb -- 4 warnings:
|
36
|
-
[5, 9, 13]:RepeatedConditionals tests switch at least 3 times (RepeatedConditional)
|
37
|
-
```
|
38
|
-
|
39
|
-
If you get this warning then you are probably not using the right abstraction or even more probable, missing an additional abstraction.
|
40
|
-
|
41
|
-
## Configuration
|
42
|
-
|
43
|
-
Reek's _Repeated Conditional_ detector offers the [Basic Smell Options](Basic-Smell-Options.md), plus:
|
44
|
-
|
45
|
-
| Option | Value | Effect |
|
46
|
-
| ---------------|-------------|---------|
|
47
|
-
| `max_ifs` | integer | The maximum number of identical conditional tests permitted before Reek raises a warning. Defaults to 2. |
|
@@ -1,16 +0,0 @@
|
|
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 their 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 [Manual Dispatch](Manual-Dispatch.md), [Repeated Conditional](Repeated-Conditional.md) and for [Nil Check](Nil-Check.md).
|