reek 5.3.1 → 5.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +0 -9
  3. data/.travis.yml +1 -2
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +1 -1
  6. data/docs/API.md +4 -4
  7. data/docs/Duplicate-Method-Call.md +68 -1
  8. data/docs/How-To-Write-New-Detectors.md +4 -4
  9. data/docs/Reek-Driven-Development.md +19 -12
  10. data/features/command_line_interface/options.feature +2 -2
  11. data/features/reports/json.feature +3 -3
  12. data/features/reports/reports.feature +4 -4
  13. data/features/reports/yaml.feature +3 -3
  14. data/lib/reek/source/source_code.rb +2 -2
  15. data/lib/reek/version.rb +1 -1
  16. data/spec/reek/ast/node_spec.rb +2 -2
  17. data/spec/reek/code_comment_spec.rb +6 -6
  18. data/spec/reek/context/code_context_spec.rb +2 -2
  19. data/spec/reek/context_builder_spec.rb +30 -30
  20. data/spec/reek/examiner_spec.rb +6 -6
  21. data/spec/reek/report/json_report_spec.rb +2 -2
  22. data/spec/reek/smell_detectors/attribute_spec.rb +32 -32
  23. data/spec/reek/smell_detectors/boolean_parameter_spec.rb +4 -4
  24. data/spec/reek/smell_detectors/class_variable_spec.rb +16 -16
  25. data/spec/reek/smell_detectors/control_parameter_spec.rb +18 -18
  26. data/spec/reek/smell_detectors/data_clump_spec.rb +16 -16
  27. data/spec/reek/smell_detectors/duplicate_method_call_spec.rb +20 -20
  28. data/spec/reek/smell_detectors/feature_envy_spec.rb +32 -32
  29. data/spec/reek/smell_detectors/instance_variable_assumption_spec.rb +12 -12
  30. data/spec/reek/smell_detectors/irresponsible_module_spec.rb +36 -36
  31. data/spec/reek/smell_detectors/long_parameter_list_spec.rb +6 -6
  32. data/spec/reek/smell_detectors/long_yield_list_spec.rb +6 -6
  33. data/spec/reek/smell_detectors/manual_dispatch_spec.rb +10 -10
  34. data/spec/reek/smell_detectors/missing_safe_method_spec.rb +8 -8
  35. data/spec/reek/smell_detectors/module_initialize_spec.rb +12 -12
  36. data/spec/reek/smell_detectors/nested_iterators_spec.rb +48 -48
  37. data/spec/reek/smell_detectors/nil_check_spec.rb +16 -16
  38. data/spec/reek/smell_detectors/repeated_conditional_spec.rb +8 -8
  39. data/spec/reek/smell_detectors/subclassed_from_core_class_spec.rb +10 -10
  40. data/spec/reek/smell_detectors/too_many_constants_spec.rb +22 -22
  41. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +16 -16
  42. data/spec/reek/smell_detectors/too_many_methods_spec.rb +6 -6
  43. data/spec/reek/smell_detectors/too_many_statements_spec.rb +10 -10
  44. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +2 -2
  45. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +2 -2
  46. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +4 -4
  47. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +18 -18
  48. data/spec/reek/smell_detectors/unused_parameters_spec.rb +4 -4
  49. data/spec/reek/smell_detectors/unused_private_method_spec.rb +24 -24
  50. data/spec/reek/smell_detectors/utility_function_spec.rb +30 -30
  51. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: db4147666bde8bb5b529a24811652b2962207c644f391bef9dd134091490ae44
4
- data.tar.gz: 1bc45d794c8c4a678801a612e533c2f1fff5a490ccc3e0e60013b95ff6a387f2
2
+ SHA1:
3
+ metadata.gz: 8e78fe759fff41903b35f67c62cd0a823258f46f
4
+ data.tar.gz: 83e26bb16a5d03352a901311e1db029a5687bfe6
5
5
  SHA512:
6
- metadata.gz: e7dddc4d7211d87887bbb3d639d499a9eb4730f1915c88793fe591f67332a549dcb88fa678bc4acd50bc6e05c8183eede890b03b6e000c036825c58e10f14b2e
7
- data.tar.gz: 49ebed1b359d43a42e843dc5e994c62c7d9ca7a9e3b0cb8640bd345664c8d8d094b7c42a14efea81280a3575c9f9f2b25b22ecceece76b09cfcc40589de7fc18
6
+ metadata.gz: a8db3fdbfd849bfd3e6e7f9f7fd13351ad92622d0aae71206960f70363077638e8de831bdb975c36c2515201c40dc294c6bf68ccc4ed12c3f78cac18b484f9c8
7
+ data.tar.gz: 8ac99b438e7fe7e9dd72e53a30cb808f4bb9e0527bac80e9cf8ce95aef5e35783e91fce47786162b3db70248915e9c056fd2ef795c68f1f54a514addfd745a7e
@@ -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:
@@ -1,4 +1,3 @@
1
- sudo: false
2
1
  dist: trusty
3
2
  cache: bundler
4
3
  language: ruby
@@ -14,7 +13,7 @@ rvm:
14
13
  - 2.5
15
14
  - 2.6
16
15
  - jruby-9.1.17.0
17
- - jruby-9.2.5.0
16
+ - jruby-9.2.6.0
18
17
  - jruby-head
19
18
  - ruby-head
20
19
  - rubinius-3
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 5.3.2 (2019-03-22)
6
+
7
+ * (troessner) Use Parser26.
8
+
5
9
  ## 5.3.1 (2019-02-08)
6
10
 
7
11
  * (Al Snow) Upgrade parser dependency
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.63.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'
@@ -23,13 +23,13 @@ Code says more than a thousand words:
23
23
  ```ruby
24
24
  require 'reek'
25
25
 
26
- source = <<-EOS
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
- EOS
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 = <<-EOS
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
- EOS
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
- Reek implements a check for _Duplicate Method Call_.
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 = <<-EOS
94
+ src = <<-RUBY
95
95
  def alfa
96
96
  bravo = 5
97
97
  end
98
- EOS
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 = <<-EOS
109
+ src = <<-RUBY
110
110
  def alfa
111
111
  bravo = 3
112
112
  charlie = 7
113
113
  end
114
- EOS
114
+ RUBY
115
115
 
116
116
  expect(src).to reek_of(:UncommunicativeVariableName,
117
117
  lines: [2],
@@ -1,8 +1,10 @@
1
- # Reek Driven Development
1
+ # Reek-Driven Development
2
2
 
3
- ## rake
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
- 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. For example, you could do that by adding a [Rake Task](Rake-Task.md) to your rakefile, which will make it easy to run Reek on all your source files whenever you need to.
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 the command `reek` will run Reek on your source code (and in this case, it fails if it finds any smells). For more detailed information about Reek's integration with Rake, see [Rake Task](Rake-Task.md).
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
- ## reek/spec
27
+ You can add Reek expectations directly into your RSpec specs.
20
28
 
21
- But there's another way; a much more effective "Reek-driven" approach: add Reek expectations directly into your Rspec specs. Here's an example taken directly from Reek's own source code:
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 "reek/spec":http://reek.rubyforge.org/rdoc/classes/Reek/Spec.html you gain access to the `reek` matcher, which returns true if and only if Reek finds smells in your code. And if the test fails, the matcher produces an error message that includes details of all the smells it found.
41
+ By requiring [`reek/spec`] you gain access to the `reek` matcher.
32
42
 
33
- ## assert
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
- If you're not yet into BDD with Rspec, you can still gain the benefits of Reek-driven development using assertions:
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.1/docs/Code-Smells.md for a list of smells
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.1/docs/Code-Smells.md for a details on each detector
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.1/docs/Uncommunicative-Method-Name.md",
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.1/docs/Uncommunicative-Variable-Name.md",
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.1/docs/Irresponsible-Module.md"
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.1/docs/Uncommunicative-Method-Name.md]
186
- [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.3.1/docs/Uncommunicative-Variable-Name.md]
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.1/docs/Uncommunicative-Method-Name.md]
213
- UncommunicativeVariableName: Smelly#x has the variable name 'y' [https://github.com/troessner/reek/blob/v5.3.1/docs/Uncommunicative-Variable-Name.md]
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.1/docs/Uncommunicative-Method-Name.md
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.1/docs/Uncommunicative-Variable-Name.md
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.1/docs/Irresponsible-Module.md
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/ruby25' }
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::Ruby25.new(AST::Builder.new).tap do |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
@@ -8,6 +8,6 @@ module Reek
8
8
  # @public
9
9
  module Version
10
10
  # @public
11
- STRING = '5.3.1'
11
+ STRING = '5.3.2'
12
12
  end
13
13
  end
@@ -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 = <<-EOS
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
- EOS
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 = <<-EOF
61
+ comment = <<-RUBY
62
62
  # :reek:DuplicateMethodCall { enabled: false }
63
63
  # :reek:NestedIterators { enabled: true }
64
- EOF
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 = <<-EOF
75
+ comment = <<-RUBY
76
76
  #:reek:DuplicateMethodCall { enabled: false } and :reek:NestedIterators { enabled: true }
77
- EOF
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 = <<-EOF
114
+ original_comment = <<-RUBY
115
115
  # Actual
116
116
  # :reek:DuplicateMethodCall { enabled: false }
117
117
  # :reek:NestedIterators { enabled: true }
118
118
  # comment
119
- EOF
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
- <<-EOS
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
- EOS
129
+ RUBY
130
130
  end
131
131
  let(:expression) { Reek::Source::SourceCode.from(src).syntax_tree }
132
132
  let(:outer) { nil }