reek 5.3.1 → 5.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +0 -9
- data/.travis.yml +1 -2
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -1
- data/docs/API.md +4 -4
- data/docs/Duplicate-Method-Call.md +68 -1
- data/docs/How-To-Write-New-Detectors.md +4 -4
- data/docs/Reek-Driven-Development.md +19 -12
- data/features/command_line_interface/options.feature +2 -2
- data/features/reports/json.feature +3 -3
- data/features/reports/reports.feature +4 -4
- data/features/reports/yaml.feature +3 -3
- data/lib/reek/source/source_code.rb +2 -2
- data/lib/reek/version.rb +1 -1
- data/spec/reek/ast/node_spec.rb +2 -2
- data/spec/reek/code_comment_spec.rb +6 -6
- data/spec/reek/context/code_context_spec.rb +2 -2
- data/spec/reek/context_builder_spec.rb +30 -30
- data/spec/reek/examiner_spec.rb +6 -6
- data/spec/reek/report/json_report_spec.rb +2 -2
- data/spec/reek/smell_detectors/attribute_spec.rb +32 -32
- data/spec/reek/smell_detectors/boolean_parameter_spec.rb +4 -4
- data/spec/reek/smell_detectors/class_variable_spec.rb +16 -16
- data/spec/reek/smell_detectors/control_parameter_spec.rb +18 -18
- data/spec/reek/smell_detectors/data_clump_spec.rb +16 -16
- data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +20 -20
- data/spec/reek/smell_detectors/feature_envy_spec.rb +32 -32
- data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +12 -12
- data/spec/reek/smell_detectors/irresponsible_module_spec.rb +36 -36
- data/spec/reek/smell_detectors/long_parameter_list_spec.rb +6 -6
- data/spec/reek/smell_detectors/long_yield_list_spec.rb +6 -6
- data/spec/reek/smell_detectors/manual_dispatch_spec.rb +10 -10
- data/spec/reek/smell_detectors/missing_safe_method_spec.rb +8 -8
- data/spec/reek/smell_detectors/module_initialize_spec.rb +12 -12
- data/spec/reek/smell_detectors/nested_iterators_spec.rb +48 -48
- data/spec/reek/smell_detectors/nil_check_spec.rb +16 -16
- data/spec/reek/smell_detectors/repeated_conditional_spec.rb +8 -8
- data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +10 -10
- data/spec/reek/smell_detectors/too_many_constants_spec.rb +22 -22
- data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +16 -16
- data/spec/reek/smell_detectors/too_many_methods_spec.rb +6 -6
- data/spec/reek/smell_detectors/too_many_statements_spec.rb +10 -10
- data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +2 -2
- data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +2 -2
- data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +4 -4
- data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +18 -18
- data/spec/reek/smell_detectors/unused_parameters_spec.rb +4 -4
- data/spec/reek/smell_detectors/unused_private_method_spec.rb +24 -24
- data/spec/reek/smell_detectors/utility_function_spec.rb +30 -30
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8e78fe759fff41903b35f67c62cd0a823258f46f
|
4
|
+
data.tar.gz: 83e26bb16a5d03352a901311e1db029a5687bfe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8db3fdbfd849bfd3e6e7f9f7fd13351ad92622d0aae71206960f70363077638e8de831bdb975c36c2515201c40dc294c6bf68ccc4ed12c3f78cac18b484f9c8
|
7
|
+
data.tar.gz: 8ac99b438e7fe7e9dd72e53a30cb808f4bb9e0527bac80e9cf8ce95aef5e35783e91fce47786162b3db70248915e9c056fd2ef795c68f1f54a514addfd745a7e
|
data/.rubocop.yml
CHANGED
@@ -24,10 +24,6 @@ Layout/DotPosition:
|
|
24
24
|
Layout/EmptyLineBetweenDefs:
|
25
25
|
AllowAdjacentOneLineDefs: true
|
26
26
|
|
27
|
-
# Use active_support's strip_heredoc to indent heredocs
|
28
|
-
Layout/IndentHeredoc:
|
29
|
-
EnforcedStyle: active_support
|
30
|
-
|
31
27
|
# Always put the closing brace on the last line
|
32
28
|
Layout/MultilineMethodCallBraceLayout:
|
33
29
|
EnforcedStyle: same_line
|
@@ -66,11 +62,6 @@ Metrics/LineLength:
|
|
66
62
|
Metrics/ParameterLists:
|
67
63
|
CountKeywordArgs: false
|
68
64
|
|
69
|
-
# EOS is a fine name to use in our specs
|
70
|
-
Naming/HeredocDelimiterNaming:
|
71
|
-
Exclude:
|
72
|
-
- 'spec/**/*'
|
73
|
-
|
74
65
|
# These files do not test classes or modules
|
75
66
|
RSpec/DescribeClass:
|
76
67
|
Exclude:
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -13,7 +13,7 @@ group :development do
|
|
13
13
|
gem 'rake', '~> 12.0'
|
14
14
|
gem 'rspec', '~> 3.0'
|
15
15
|
gem 'rspec-benchmark', '~> 0.4.0'
|
16
|
-
gem 'rubocop', '~> 0.
|
16
|
+
gem 'rubocop', '~> 0.66.0'
|
17
17
|
gem 'rubocop-rspec', '~> 1.32.0'
|
18
18
|
gem 'simplecov', '~> 0.16.1'
|
19
19
|
gem 'yard', '~> 0.9.5'
|
data/docs/API.md
CHANGED
@@ -23,13 +23,13 @@ Code says more than a thousand words:
|
|
23
23
|
```ruby
|
24
24
|
require 'reek'
|
25
25
|
|
26
|
-
source = <<-
|
26
|
+
source = <<-RUBY
|
27
27
|
class Dirty
|
28
28
|
def m(a,b,c)
|
29
29
|
puts a,b
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
RUBY
|
33
33
|
|
34
34
|
reporter = Reek::Report::TextReport.new
|
35
35
|
examiner = Reek::Examiner.new source
|
@@ -117,13 +117,13 @@ require 'reek'
|
|
117
117
|
config_hash = { 'IrresponsibleModule' => { 'enabled' => false } }
|
118
118
|
configuration = Reek::Configuration::AppConfiguration.from_hash config_hash
|
119
119
|
|
120
|
-
source = <<-
|
120
|
+
source = <<-RUBY
|
121
121
|
class Dirty
|
122
122
|
def call_me(a,b)
|
123
123
|
puts a,b
|
124
124
|
end
|
125
125
|
end
|
126
|
-
|
126
|
+
RUBY
|
127
127
|
|
128
128
|
reporter = Reek::Report::TextReport.new
|
129
129
|
examiner = Reek::Examiner.new(source, configuration: configuration); nil
|
@@ -3,7 +3,74 @@
|
|
3
3
|
## Introduction
|
4
4
|
|
5
5
|
Duplication occurs when two fragments of code look nearly identical, or when two fragments of code have nearly identical effects at some conceptual level.
|
6
|
-
|
6
|
+
|
7
|
+
Let's look at an example that is quite common in the Rails world:
|
8
|
+
|
9
|
+
```Ruby
|
10
|
+
def not_production?
|
11
|
+
Rails.env.development? || Rails.env.test?
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
While this duplicate usage of `Rails.env` might seem innocuous there are 2 problems with it:
|
16
|
+
|
17
|
+
1.) Efficiency
|
18
|
+
|
19
|
+
```Ruby
|
20
|
+
Rails.env.development? || Rails.env.test?
|
21
|
+
```
|
22
|
+
|
23
|
+
is not as efficient as it could be. If the call to `env` is not memoized your basically paying twice in terms of computation for something that you should only pay once.
|
24
|
+
|
25
|
+
Here
|
26
|
+
|
27
|
+
```Ruby
|
28
|
+
Rails.env.development? || Rails.env.test?
|
29
|
+
```
|
30
|
+
|
31
|
+
you have 4 method calls while here:
|
32
|
+
|
33
|
+
```Ruby
|
34
|
+
env = Rails.env
|
35
|
+
env.development? || env.test?
|
36
|
+
```
|
37
|
+
|
38
|
+
you have one assignment (which is very cheap in terms of computation) and 3 method calls.
|
39
|
+
The difference might not be much here but just imagine you're writing a high performance app or you doing some expensive database calls in each method call.
|
40
|
+
|
41
|
+
It doesn't really matter though if the efficiency difference is significant. This is a matter of principle - we believe that being efficient is one of the vital traits of good software.
|
42
|
+
|
43
|
+
2.) Maintainability
|
44
|
+
|
45
|
+
The second point is a bit more subtle. This
|
46
|
+
|
47
|
+
```Ruby
|
48
|
+
env = Rails.env
|
49
|
+
env.development? || env.test?
|
50
|
+
```
|
51
|
+
|
52
|
+
is a lot more intention revealing than
|
53
|
+
|
54
|
+
```Ruby
|
55
|
+
Rails.env.development? || Rails.env.test?
|
56
|
+
```
|
57
|
+
|
58
|
+
Here
|
59
|
+
|
60
|
+
```Ruby
|
61
|
+
env = Rails.env
|
62
|
+
env.development? || env.test?
|
63
|
+
```
|
64
|
+
|
65
|
+
I'm very clear on what I do: I get the environment and then I run some checks on it.
|
66
|
+
|
67
|
+
Here
|
68
|
+
|
69
|
+
```Ruby
|
70
|
+
Rails.env.development? || Rails.env.test?
|
71
|
+
```
|
72
|
+
|
73
|
+
I'm not very clear on what I do and it requires quite more mental effort: Ok, so I'm talking to Rails, getting the environment and then running a check on it ...or .....oh, I get the same Rails constant again, get the same environment and run another check on it.
|
7
74
|
|
8
75
|
## Example
|
9
76
|
|
@@ -91,11 +91,11 @@ Here's what it looks like for `UncommunicativeVariableName`:
|
|
91
91
|
|
92
92
|
```Ruby
|
93
93
|
it 'reports the right values' do
|
94
|
-
src = <<-
|
94
|
+
src = <<-RUBY
|
95
95
|
def alfa
|
96
96
|
bravo = 5
|
97
97
|
end
|
98
|
-
|
98
|
+
RUBY
|
99
99
|
|
100
100
|
expect(src).to reek_of(:UncommunicativeVariableName,
|
101
101
|
lines: [2],
|
@@ -106,12 +106,12 @@ it 'reports the right values' do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
it 'does count all occurences' do
|
109
|
-
src = <<-
|
109
|
+
src = <<-RUBY
|
110
110
|
def alfa
|
111
111
|
bravo = 3
|
112
112
|
charlie = 7
|
113
113
|
end
|
114
|
-
|
114
|
+
RUBY
|
115
115
|
|
116
116
|
expect(src).to reek_of(:UncommunicativeVariableName,
|
117
117
|
lines: [2],
|
@@ -1,8 +1,10 @@
|
|
1
|
-
# Reek
|
1
|
+
# Reek-Driven Development
|
2
2
|
|
3
|
-
|
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
4
|
|
5
|
-
|
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.
|
6
8
|
|
7
9
|
```Ruby
|
8
10
|
require 'reek/rake/task'
|
@@ -14,13 +16,21 @@ Reek::Rake::Task.new do |t|
|
|
14
16
|
end
|
15
17
|
```
|
16
18
|
|
17
|
-
Now
|
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`
|
18
26
|
|
19
|
-
|
27
|
+
You can add Reek expectations directly into your RSpec specs.
|
20
28
|
|
21
|
-
|
29
|
+
This example is from Reek's own source code:
|
22
30
|
|
23
31
|
```Ruby
|
32
|
+
require 'reek/spec'
|
33
|
+
|
24
34
|
it 'contains no code smells' do
|
25
35
|
Pathname.glob('lib/**/*.rb').each do |file|
|
26
36
|
expect(file).not_to reek
|
@@ -28,12 +38,9 @@ it 'contains no code smells' do
|
|
28
38
|
end
|
29
39
|
```
|
30
40
|
|
31
|
-
By requiring
|
41
|
+
By requiring [`reek/spec`] you gain access to the `reek` matcher.
|
32
42
|
|
33
|
-
|
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.
|
34
44
|
|
35
|
-
|
45
|
+
[`reek/spec`]: ../lib/reek/spec.rb
|
36
46
|
|
37
|
-
```Ruby
|
38
|
-
assert !Dir['lib/**/*.rb'].to_source.smelly?
|
39
|
-
```
|
@@ -43,7 +43,7 @@ Feature: Reek can be controlled using command-line options
|
|
43
43
|
-c, --config FILE Read configuration options from FILE
|
44
44
|
--smell SMELL Only look for a specific smell.
|
45
45
|
Call it like this: reek --smell MissingSafeMethod source.rb
|
46
|
-
Check out https://github.com/troessner/reek/blob/v5.3.
|
46
|
+
Check out https://github.com/troessner/reek/blob/v5.3.2/docs/Code-Smells.md for a list of smells
|
47
47
|
--stdin-filename FILE When passing code in via pipe, assume this filename when checking file or directory rules in the config.
|
48
48
|
|
49
49
|
Generate a todo list:
|
@@ -120,5 +120,5 @@ Feature: Reek can be controlled using command-line options
|
|
120
120
|
UnusedPrivateMethod
|
121
121
|
UtilityFunction
|
122
122
|
|
123
|
-
Check out https://github.com/troessner/reek/blob/v5.3.
|
123
|
+
Check out https://github.com/troessner/reek/blob/v5.3.2/docs/Code-Smells.md for a details on each detector
|
124
124
|
"""
|
@@ -24,7 +24,7 @@ Feature: Report smells using simple JSON layout
|
|
24
24
|
"context": "Smelly#x",
|
25
25
|
"lines": [ 4 ],
|
26
26
|
"message": "has the name 'x'",
|
27
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v5.3.
|
27
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Method-Name.md",
|
28
28
|
"name": "x"
|
29
29
|
},
|
30
30
|
{
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple JSON layout
|
|
33
33
|
"context": "Smelly#x",
|
34
34
|
"lines": [ 5 ],
|
35
35
|
"message": "has the variable name 'y'",
|
36
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v5.3.
|
36
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Variable-Name.md",
|
37
37
|
"name": "y"
|
38
38
|
}
|
39
39
|
]
|
@@ -53,7 +53,7 @@ Feature: Report smells using simple JSON layout
|
|
53
53
|
1
|
54
54
|
],
|
55
55
|
"message": "has no descriptive comment",
|
56
|
-
"documentation_link": "https://github.com/troessner/reek/blob/v5.3.
|
56
|
+
"documentation_link": "https://github.com/troessner/reek/blob/v5.3.2/docs/Irresponsible-Module.md"
|
57
57
|
}
|
58
58
|
]
|
59
59
|
"""
|
@@ -182,8 +182,8 @@ Feature: Correctly formatted reports
|
|
182
182
|
And it reports:
|
183
183
|
"""
|
184
184
|
smelly.rb -- 2 warnings:
|
185
|
-
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.3.
|
186
|
-
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.3.
|
185
|
+
[4]:UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Method-Name.md]
|
186
|
+
[5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Variable-Name.md]
|
187
187
|
"""
|
188
188
|
|
189
189
|
Examples:
|
@@ -209,8 +209,8 @@ Feature: Correctly formatted reports
|
|
209
209
|
And it reports:
|
210
210
|
"""
|
211
211
|
smelly.rb -- 2 warnings:
|
212
|
-
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.3.
|
213
|
-
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.3.
|
212
|
+
UncommunicativeMethodName: Smelly#x has the name 'x' [https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Method-Name.md]
|
213
|
+
UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Variable-Name.md]
|
214
214
|
"""
|
215
215
|
|
216
216
|
Examples:
|
@@ -25,7 +25,7 @@ Feature: Report smells using simple YAML layout
|
|
25
25
|
smell_type: UncommunicativeMethodName
|
26
26
|
source: smelly.rb
|
27
27
|
name: x
|
28
|
-
documentation_link: https://github.com/troessner/reek/blob/v5.3.
|
28
|
+
documentation_link: https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Method-Name.md
|
29
29
|
- context: Smelly#x
|
30
30
|
lines:
|
31
31
|
- 5
|
@@ -33,7 +33,7 @@ Feature: Report smells using simple YAML layout
|
|
33
33
|
smell_type: UncommunicativeVariableName
|
34
34
|
source: smelly.rb
|
35
35
|
name: y
|
36
|
-
documentation_link: https://github.com/troessner/reek/blob/v5.3.
|
36
|
+
documentation_link: https://github.com/troessner/reek/blob/v5.3.2/docs/Uncommunicative-Variable-Name.md
|
37
37
|
"""
|
38
38
|
|
39
39
|
Scenario: Indicate smells and print them as yaml when using STDIN
|
@@ -48,5 +48,5 @@ Feature: Report smells using simple YAML layout
|
|
48
48
|
lines:
|
49
49
|
- 1
|
50
50
|
message: has no descriptive comment
|
51
|
-
documentation_link: https://github.com/troessner/reek/blob/v5.3.
|
51
|
+
documentation_link: https://github.com/troessner/reek/blob/v5.3.2/docs/Irresponsible-Module.md
|
52
52
|
"""
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../cli/silencer'
|
4
|
-
Reek::CLI::Silencer.without_warnings { require 'parser/
|
4
|
+
Reek::CLI::Silencer.without_warnings { require 'parser/ruby26' }
|
5
5
|
require_relative '../tree_dresser'
|
6
6
|
require_relative '../ast/node'
|
7
7
|
require_relative '../ast/builder'
|
@@ -53,7 +53,7 @@ module Reek
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.default_parser
|
56
|
-
Parser::
|
56
|
+
Parser::Ruby26.new(AST::Builder.new).tap do |parser|
|
57
57
|
diagnostics = parser.diagnostics
|
58
58
|
diagnostics.all_errors_are_fatal = true
|
59
59
|
diagnostics.ignore_warnings = true
|
data/lib/reek/version.rb
CHANGED
data/spec/reek/ast/node_spec.rb
CHANGED
@@ -68,7 +68,7 @@ RSpec.describe Reek::AST::Node do
|
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'finds 3 ifs in a class' do
|
71
|
-
src = <<-
|
71
|
+
src = <<-RUBY
|
72
72
|
class Scrunch
|
73
73
|
def first
|
74
74
|
return @field == :sym ? 0 : 3;
|
@@ -82,7 +82,7 @@ RSpec.describe Reek::AST::Node do
|
|
82
82
|
raise 'flu!' unless @field == :sym
|
83
83
|
end
|
84
84
|
end
|
85
|
-
|
85
|
+
RUBY
|
86
86
|
ast = Reek::Source::SourceCode.from(src).syntax_tree
|
87
87
|
expect(ast.each_node(:if).to_a.length).to eq(3)
|
88
88
|
end
|
@@ -58,10 +58,10 @@ RSpec.describe Reek::CodeComment do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'parses multiple hashed options' do
|
61
|
-
comment = <<-
|
61
|
+
comment = <<-RUBY
|
62
62
|
# :reek:DuplicateMethodCall { enabled: false }
|
63
63
|
# :reek:NestedIterators { enabled: true }
|
64
|
-
|
64
|
+
RUBY
|
65
65
|
config = build(:code_comment, comment: comment).config
|
66
66
|
|
67
67
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
@@ -72,9 +72,9 @@ RSpec.describe Reek::CodeComment do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'parses multiple hashed options on the same line' do
|
75
|
-
comment = <<-
|
75
|
+
comment = <<-RUBY
|
76
76
|
#:reek:DuplicateMethodCall { enabled: false } and :reek:NestedIterators { enabled: true }
|
77
|
-
|
77
|
+
RUBY
|
78
78
|
config = build(:code_comment, comment: comment).config
|
79
79
|
|
80
80
|
expect(config).to include('DuplicateMethodCall', 'NestedIterators')
|
@@ -111,12 +111,12 @@ RSpec.describe Reek::CodeComment do
|
|
111
111
|
end
|
112
112
|
|
113
113
|
it 'removes the configuration options from the comment' do
|
114
|
-
original_comment = <<-
|
114
|
+
original_comment = <<-RUBY
|
115
115
|
# Actual
|
116
116
|
# :reek:DuplicateMethodCall { enabled: false }
|
117
117
|
# :reek:NestedIterators { enabled: true }
|
118
118
|
# comment
|
119
|
-
|
119
|
+
RUBY
|
120
120
|
comment = build(:code_comment, comment: original_comment)
|
121
121
|
|
122
122
|
expect(comment.send(:sanitized_comment)).to eq('Actual comment')
|
@@ -120,13 +120,13 @@ RSpec.describe Reek::Context::CodeContext do
|
|
120
120
|
|
121
121
|
describe '#config_for' do
|
122
122
|
let(:src) do
|
123
|
-
<<-
|
123
|
+
<<-RUBY
|
124
124
|
# :reek:DuplicateMethodCall { allow_calls: [ puts ] }')
|
125
125
|
def repeated_greeting
|
126
126
|
puts 'Hello!'
|
127
127
|
puts 'Hello!'
|
128
128
|
end
|
129
|
-
|
129
|
+
RUBY
|
130
130
|
end
|
131
131
|
let(:expression) { Reek::Source::SourceCode.from(src).syntax_tree }
|
132
132
|
let(:outer) { nil }
|