reek 3.3.0 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +2 -2
- data/.travis.yml +3 -2
- data/CHANGELOG.md +7 -1
- data/config/defaults.reek +2 -1
- data/docs/API.md +102 -25
- data/docs/Code-Smells.md +2 -2
- data/docs/Nested-Iterators.md +1 -0
- data/docs/Too-Many-Methods.md +1 -1
- data/lib/reek/ast/object_refs.rb +1 -0
- data/lib/reek/cli/option_interpreter.rb +1 -1
- data/lib/reek/code_comment.rb +3 -0
- data/lib/reek/context/code_context.rb +1 -1
- data/lib/reek/examiner.rb +2 -0
- data/lib/reek/rake/task.rb +10 -1
- data/lib/reek/report/formatter.rb +2 -2
- data/lib/reek/report/report.rb +10 -13
- data/lib/reek/smells/attribute.rb +1 -1
- data/lib/reek/smells/nested_iterators.rb +1 -1
- data/lib/reek/smells/nil_check.rb +1 -1
- data/lib/reek/smells/smell_detector.rb +1 -1
- data/lib/reek/smells/smell_warning.rb +7 -5
- data/lib/reek/source/source_code.rb +1 -1
- data/lib/reek/spec.rb +1 -1
- data/lib/reek/spec/should_reek.rb +1 -1
- data/lib/reek/tree_dresser.rb +19 -4
- data/lib/reek/version.rb +1 -1
- data/spec/reek/ast/node_spec.rb +5 -5
- data/spec/reek/ast/sexp_extensions_spec.rb +41 -41
- data/spec/reek/ast/sexp_formatter_spec.rb +9 -9
- data/spec/reek/context/code_context_spec.rb +7 -7
- data/spec/reek/context/method_context_spec.rb +9 -9
- data/spec/reek/context/singleton_method_context_spec.rb +2 -2
- data/spec/reek/report/html_report_spec.rb +2 -1
- data/spec/reek/smells/class_variable_spec.rb +2 -2
- data/spec/reek/smells/nested_iterators_spec.rb +5 -0
- data/spec/reek/source/source_code_spec.rb +1 -1
- data/spec/reek/spec/should_reek_spec.rb +1 -1
- data/spec/reek/tree_dresser_spec.rb +41 -7
- data/spec/spec_helper.rb +1 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 18055c0f9c08fb0e795cb4417885156291c9f5b7
|
4
|
+
data.tar.gz: b2d41cb4510dd092450c82bae4664bbbb7a10d50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92722d3bdd09267e2c5858414b6f91cf066a6f9c3596033a3845d1c2d7cd768d17eb29e932af6d7ea8a432081f77b6f77092051288903b0377f11f6137c292ff
|
7
|
+
data.tar.gz: 0124c0f5b7d1c4f0f580b545757d1f94d51c2f93310b2dfe922abaa9ef241fc91a4ddadbad07832d6d5e92e99b0d4186b70f194f54f68f995693fbc70afc15e5
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -14,9 +14,9 @@ Metrics/ClassLength:
|
|
14
14
|
Metrics/MethodLength:
|
15
15
|
Max: 15
|
16
16
|
|
17
|
-
# Be
|
17
|
+
# Be rather lenient with line length
|
18
18
|
Metrics/LineLength:
|
19
|
-
Max:
|
19
|
+
Max: 120
|
20
20
|
|
21
21
|
# Indent one level for follow-up lines
|
22
22
|
Style/MultilineOperationIndentation:
|
data/.travis.yml
CHANGED
@@ -20,11 +20,12 @@ matrix:
|
|
20
20
|
allow_failures:
|
21
21
|
- rvm: jruby
|
22
22
|
- rvm: jruby-head
|
23
|
+
- rvm: rbx-2
|
23
24
|
- rvm: ruby-head
|
24
25
|
fast_finish: true
|
25
26
|
notifications:
|
26
|
-
|
27
|
+
email:
|
27
28
|
- timo.roessner@googlemail.com
|
28
29
|
- matijs@matijs.net
|
29
30
|
- chastell@chastell.net
|
30
|
-
irc:
|
31
|
+
irc: irc.freenode.org#reek
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 3.3.1 (2015-09-03)
|
6
|
+
|
7
|
+
* (troessner) Fix file list as argument in rake task
|
8
|
+
* (troessner) Ignore `Object#tap` for NestedIterators
|
9
|
+
* (mvz) Ensure all YAML methods are loaded (workaround for #653)
|
10
|
+
|
5
11
|
## 3.3.0 (2015-08-23)
|
6
12
|
|
7
13
|
* (HParker / Adam Hess) add support for or-assign constants
|
@@ -9,7 +15,7 @@
|
|
9
15
|
|
10
16
|
## 3.2.1 (2015-08-17)
|
11
17
|
|
12
|
-
* Revert 864f0a9 to hotfix
|
18
|
+
* (troessner) Revert 864f0a9 to hotfix #642
|
13
19
|
|
14
20
|
## 3.2.0 (2015-08-17)
|
15
21
|
|
data/config/defaults.reek
CHANGED
data/docs/API.md
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
# Using `reek` inside your Ruby application
|
2
2
|
|
3
|
-
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Either standalone via
|
4
6
|
|
5
7
|
```bash
|
6
8
|
gem install reek
|
7
9
|
```
|
8
10
|
|
9
|
-
|
11
|
+
or by adding
|
12
|
+
|
13
|
+
```
|
14
|
+
gem 'reek'
|
15
|
+
```
|
16
|
+
|
17
|
+
to your Gemfile.
|
18
|
+
|
19
|
+
## Quick start
|
10
20
|
|
11
|
-
|
21
|
+
Code says more than a thousand words:
|
12
22
|
|
13
23
|
```ruby
|
14
24
|
require 'reek'
|
15
25
|
|
16
|
-
source = <<-
|
26
|
+
source = <<-EOS
|
17
27
|
class Dirty
|
18
|
-
|
19
|
-
|
20
|
-
puts @screen.title
|
21
|
-
@screen = widgets.map { |w| w.each { |key| key += 3 * x } }
|
22
|
-
puts @screen.contents
|
23
|
-
fail
|
28
|
+
def m(a,b,c)
|
29
|
+
puts a,b
|
24
30
|
end
|
25
31
|
end
|
26
|
-
|
32
|
+
EOS
|
27
33
|
|
28
34
|
reporter = Reek::Report::TextReport.new
|
29
35
|
examiner = Reek::Examiner.new(source)
|
@@ -31,16 +37,22 @@ reporter.add_examiner examiner
|
|
31
37
|
reporter.show
|
32
38
|
```
|
33
39
|
|
34
|
-
This
|
35
|
-
|
36
|
-
`Reek::Examiner.new` can take `source` as `String`, `File` or `IO`.
|
40
|
+
This would output the following on STDOUT:
|
37
41
|
|
38
42
|
```
|
39
|
-
|
40
|
-
|
43
|
+
string -- 5 warnings:
|
44
|
+
Dirty has no descriptive comment (IrresponsibleModule)
|
45
|
+
Dirty#m has the name 'm' (UncommunicativeMethodName)
|
46
|
+
Dirty#m has the parameter name 'a' (UncommunicativeParameterName)
|
47
|
+
Dirty#m has the parameter name 'b' (UncommunicativeParameterName)
|
48
|
+
Dirty#m has unused parameter 'c' (UnusedParameters)
|
41
49
|
```
|
42
50
|
|
43
|
-
|
51
|
+
Note that `Reek::Examiner.new` can take `source` as `String`, `Pathname`, `File` or `IO`.
|
52
|
+
|
53
|
+
## Choosing your output format
|
54
|
+
|
55
|
+
Besides normal text output, `reek` can generate output in YAML,
|
44
56
|
JSON, HTML and XML by using the following Report types:
|
45
57
|
|
46
58
|
```
|
@@ -51,6 +63,78 @@ HTMLReport
|
|
51
63
|
XMLReport
|
52
64
|
```
|
53
65
|
|
66
|
+
## Configuration
|
67
|
+
|
68
|
+
Given you have the following configuration file called `config.reek` in your root directory:
|
69
|
+
|
70
|
+
```Yaml
|
71
|
+
---
|
72
|
+
IrresponsibleModule:
|
73
|
+
enabled: false
|
74
|
+
```
|
75
|
+
|
76
|
+
You can now use either
|
77
|
+
|
78
|
+
```Ruby
|
79
|
+
Reek::Configuration::AppConfiguration.from_path Pathname.new('config.reek`)
|
80
|
+
```
|
81
|
+
|
82
|
+
but you can also pass a hash via `Reek::Configuration::AppConfiguration.from_map`.
|
83
|
+
|
84
|
+
This hash can have the following 3 keys:
|
85
|
+
|
86
|
+
1.) directory_directives [Hash] for instance:
|
87
|
+
|
88
|
+
```Ruby
|
89
|
+
{ Pathname("spec/samples/three_clean_files/") =>
|
90
|
+
{ Reek::Smells::UtilityFunction => { "enabled" => false } } }
|
91
|
+
```
|
92
|
+
|
93
|
+
2.) default_directive [Hash] for instance:
|
94
|
+
|
95
|
+
```Ruby
|
96
|
+
{ Reek::Smells::IrresponsibleModule => { "enabled" => false } }
|
97
|
+
```
|
98
|
+
|
99
|
+
3.) excluded_paths [Array] for instance:
|
100
|
+
|
101
|
+
```Ruby
|
102
|
+
[ Pathname('spec/samples/two_smelly_files') ]
|
103
|
+
```
|
104
|
+
|
105
|
+
Given the example above you should load that as "default directive" which means that it will
|
106
|
+
be the default configuration for smell types for which there is
|
107
|
+
no "directory directive" (so a directory-specific configuration):
|
108
|
+
|
109
|
+
```Ruby
|
110
|
+
require 'reek'
|
111
|
+
|
112
|
+
default_directive = { Reek::Smells::IrresponsibleModule => { 'enabled' => false } }
|
113
|
+
configuration = Reek::Configuration::AppConfiguration.from_map default_directive: default_directive
|
114
|
+
|
115
|
+
source = <<-EOS
|
116
|
+
class Dirty
|
117
|
+
def call_me(a,b)
|
118
|
+
puts a,b
|
119
|
+
end
|
120
|
+
end
|
121
|
+
EOS
|
122
|
+
|
123
|
+
reporter = Reek::Report::TextReport.new
|
124
|
+
examiner = Reek::Examiner.new(source, configuration: configuration); nil
|
125
|
+
reporter.add_examiner examiner; nil
|
126
|
+
reporter.show
|
127
|
+
```
|
128
|
+
|
129
|
+
This would now only report the `UncommunicativeParameterName` but not the `IrresponsibleModule`
|
130
|
+
for the `Dirty` class:
|
131
|
+
|
132
|
+
```
|
133
|
+
string -- 2 warnings:
|
134
|
+
Dirty#call_me has the parameter name 'a' (UncommunicativeParameterName)
|
135
|
+
Dirty#call_me has the parameter name 'b' (UncommunicativeParameterName)
|
136
|
+
```
|
137
|
+
|
54
138
|
## Accessing the smell warnings directly
|
55
139
|
|
56
140
|
You can also access the smells detected by an examiner directly:
|
@@ -59,14 +143,7 @@ You can also access the smells detected by an examiner directly:
|
|
59
143
|
require 'reek'
|
60
144
|
|
61
145
|
source = <<-END
|
62
|
-
class
|
63
|
-
# This method smells of :reek:NestedIterators but ignores them
|
64
|
-
def awful(x, y, offset = 0, log = false)
|
65
|
-
puts @screen.title
|
66
|
-
@screen = widgets.map { |w| w.each { |key| key += 3 * x } }
|
67
|
-
puts @screen.contents
|
68
|
-
fail
|
69
|
-
end
|
146
|
+
class C
|
70
147
|
end
|
71
148
|
END
|
72
149
|
|
data/docs/Code-Smells.md
CHANGED
@@ -4,7 +4,7 @@ Smells are indicators of where your code might be hard to read, maintain or evol
|
|
4
4
|
|
5
5
|
Reek currently includes checks for the following smells:
|
6
6
|
|
7
|
-
* [Attribute](Attribute.md)
|
7
|
+
* [Attribute](Attribute.md)
|
8
8
|
* [Class Variable](Class-Variable.md)
|
9
9
|
* [Control Couple](Control-Couple.md), including
|
10
10
|
* [Boolean Parameter](Boolean-Parameter.md)
|
@@ -31,4 +31,4 @@ Reek currently includes checks for the following smells:
|
|
31
31
|
* [Uncommunicative Module Name](Uncommunicative-Module-Name.md)
|
32
32
|
* [Uncommunicative Parameter Name](Uncommunicative-Parameter-Name.md)
|
33
33
|
* [Uncommunicative Variable Name](Uncommunicative-Variable-Name.md)
|
34
|
-
* [Unused Parameters](Unused-Parameters.md)
|
34
|
+
* [Unused Parameters](Unused-Parameters.md)
|
data/docs/Nested-Iterators.md
CHANGED
data/docs/Too-Many-Methods.md
CHANGED
@@ -52,4 +52,4 @@ would cause reek to emit the same warning as in the example above.
|
|
52
52
|
|
53
53
|
| Option | Value | Effect |
|
54
54
|
| ---------------|-------------|---------|
|
55
|
-
| max_methods | integer | The maximum number of methods that are permitted. Defaults to
|
55
|
+
| max_methods | integer | The maximum number of methods that are permitted. Defaults to 15 |
|
data/lib/reek/ast/object_refs.rb
CHANGED
data/lib/reek/code_comment.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'private_attr/everywhere'
|
3
3
|
|
4
|
+
# NOTE: Work-around for https://github.com/tenderlove/psych/issues/223
|
5
|
+
require 'psych.rb' if Object.const_defined?(:Psych)
|
6
|
+
|
4
7
|
module Reek
|
5
8
|
#
|
6
9
|
# A comment header from an abstract syntax tree; found directly above
|
@@ -137,7 +137,7 @@ module Reek
|
|
137
137
|
#
|
138
138
|
# @param visibility [Symbol]
|
139
139
|
# @param names [Array<Symbol>]
|
140
|
-
def track_visibility(visibility, names
|
140
|
+
def track_visibility(visibility, names)
|
141
141
|
if names.any?
|
142
142
|
children.each do |child|
|
143
143
|
child.visibility = visibility if names.include? child.name
|
data/lib/reek/examiner.rb
CHANGED
@@ -24,6 +24,8 @@ module Reek
|
|
24
24
|
# @param filter_by_smells [Array<String>]
|
25
25
|
# List of smell types to filter by.
|
26
26
|
#
|
27
|
+
# @param configuration [Configuration::AppConfiguration]
|
28
|
+
# The configuration for this Examiner.
|
27
29
|
def initialize(source,
|
28
30
|
filter_by_smells = [],
|
29
31
|
configuration: Configuration::AppConfiguration.default)
|
data/lib/reek/rake/task.rb
CHANGED
@@ -44,7 +44,7 @@ module Reek
|
|
44
44
|
# Glob pattern to match source files.
|
45
45
|
# Setting the REEK_SRC environment variable overrides this.
|
46
46
|
# Defaults to 'lib/**/*.rb'.
|
47
|
-
|
47
|
+
attr_reader :source_files
|
48
48
|
|
49
49
|
# String containing commandline options to be passed to Reek.
|
50
50
|
# Setting the REEK_OPTS environment variable overrides this value.
|
@@ -71,10 +71,19 @@ module Reek
|
|
71
71
|
define_task
|
72
72
|
end
|
73
73
|
|
74
|
+
def source_files=(files)
|
75
|
+
raise ArgumentError, no_string_given_for_file_list_warning unless files.is_a?(String)
|
76
|
+
@source_files = FileList[files]
|
77
|
+
end
|
78
|
+
|
74
79
|
private
|
75
80
|
|
76
81
|
private_attr_reader :fail_on_error, :name, :verbose
|
77
82
|
|
83
|
+
def no_string_given_for_file_list_warning
|
84
|
+
"File list should be a String that can contain a glob pattern, e.g. '{app,lib,spec}/**/*.rb'"
|
85
|
+
end
|
86
|
+
|
78
87
|
def define_task
|
79
88
|
desc 'Check for code smells'
|
80
89
|
task(name) { run_task }
|
@@ -10,7 +10,7 @@ module Reek
|
|
10
10
|
#
|
11
11
|
# @api private
|
12
12
|
module Formatter
|
13
|
-
def self.format_list(warnings, formatter
|
13
|
+
def self.format_list(warnings, formatter: SimpleWarningFormatter.new)
|
14
14
|
warnings.map do |warning|
|
15
15
|
" #{formatter.format warning}"
|
16
16
|
end.join("\n")
|
@@ -31,7 +31,7 @@ module Reek
|
|
31
31
|
#
|
32
32
|
# @api private
|
33
33
|
class SimpleWarningFormatter
|
34
|
-
def initialize(location_formatter
|
34
|
+
def initialize(location_formatter: BlankLocationFormatter)
|
35
35
|
@location_formatter = location_formatter
|
36
36
|
end
|
37
37
|
|
data/lib/reek/report/report.rb
CHANGED
@@ -16,13 +16,15 @@ module Reek
|
|
16
16
|
# @api private
|
17
17
|
WARNINGS_COLOR = :red
|
18
18
|
|
19
|
-
def initialize(
|
19
|
+
def initialize(heading_formatter: HeadingFormatter::Quiet,
|
20
|
+
report_formatter: Formatter, sort_by_issue_count: false,
|
21
|
+
warning_formatter: SimpleWarningFormatter.new)
|
20
22
|
@examiners = []
|
23
|
+
@heading_formatter = heading_formatter.new(report_formatter)
|
24
|
+
@report_formatter = report_formatter
|
25
|
+
@sort_by_issue_count = sort_by_issue_count
|
21
26
|
@total_smell_count = 0
|
22
|
-
@
|
23
|
-
@warning_formatter = options.fetch :warning_formatter, SimpleWarningFormatter.new
|
24
|
-
@report_formatter = options.fetch :report_formatter, Formatter
|
25
|
-
@sort_by_issue_count = options.fetch :sort_by_issue_count, false
|
27
|
+
@warning_formatter = warning_formatter
|
26
28
|
end
|
27
29
|
|
28
30
|
# Add Examiner to report on. The report will output results for all
|
@@ -56,7 +58,7 @@ module Reek
|
|
56
58
|
|
57
59
|
private
|
58
60
|
|
59
|
-
private_attr_reader :examiners, :
|
61
|
+
private_attr_reader :examiners, :heading_formatter, :report_formatter,
|
60
62
|
:sort_by_issue_count, :warning_formatter
|
61
63
|
end
|
62
64
|
|
@@ -89,7 +91,7 @@ module Reek
|
|
89
91
|
result = heading_formatter.header(examiner)
|
90
92
|
if examiner.smelly?
|
91
93
|
formatted_list = report_formatter.format_list(examiner.smells,
|
92
|
-
warning_formatter)
|
94
|
+
formatter: warning_formatter)
|
93
95
|
result += ":\n#{formatted_list}"
|
94
96
|
end
|
95
97
|
result
|
@@ -104,11 +106,6 @@ module Reek
|
|
104
106
|
s = total_smell_count == 1 ? '' : 's'
|
105
107
|
Rainbow("#{total_smell_count} total warning#{s}\n").color(colour)
|
106
108
|
end
|
107
|
-
|
108
|
-
def heading_formatter
|
109
|
-
@heading_formatter ||=
|
110
|
-
options.fetch(:heading_formatter, HeadingFormatter::Quiet).new(report_formatter)
|
111
|
-
end
|
112
109
|
end
|
113
110
|
|
114
111
|
#
|
@@ -139,7 +136,7 @@ module Reek
|
|
139
136
|
class HTMLReport < Base
|
140
137
|
require 'erb'
|
141
138
|
|
142
|
-
def show(target_path
|
139
|
+
def show(target_path: Pathname.new('reek.html'))
|
143
140
|
template_path = Pathname.new("#{__dir__}/html_report.html.erb")
|
144
141
|
File.write target_path, ERB.new(template_path.read).result(binding)
|
145
142
|
puts 'HTML file saved'
|
@@ -19,7 +19,7 @@ module Reek
|
|
19
19
|
# The name of the config field that sets the names of any
|
20
20
|
# methods for which nesting should not be considered
|
21
21
|
IGNORE_ITERATORS_KEY = 'ignore_iterators'
|
22
|
-
DEFAULT_IGNORE_ITERATORS = []
|
22
|
+
DEFAULT_IGNORE_ITERATORS = ['tap']
|
23
23
|
|
24
24
|
def self.default_config
|
25
25
|
super.merge(
|
@@ -11,12 +11,14 @@ module Reek
|
|
11
11
|
attr_reader :context, :lines, :message, :parameters, :smell_detector
|
12
12
|
def_delegators :smell_detector, :smell_category, :smell_type, :source
|
13
13
|
|
14
|
-
|
14
|
+
# FIXME: switch to required kwargs when dropping Ruby 2.0 compatibility
|
15
|
+
def initialize(smell_detector, context: '', lines: raise, message: raise,
|
16
|
+
parameters: {})
|
15
17
|
@smell_detector = smell_detector
|
16
|
-
@context =
|
17
|
-
@lines =
|
18
|
-
@message =
|
19
|
-
@parameters =
|
18
|
+
@context = context.to_s
|
19
|
+
@lines = lines
|
20
|
+
@message = message
|
21
|
+
@parameters = parameters
|
20
22
|
end
|
21
23
|
|
22
24
|
def hash
|
@@ -23,7 +23,7 @@ module Reek
|
|
23
23
|
# code - Ruby code as String
|
24
24
|
# description - 'STDIN', 'string' or a filepath as String
|
25
25
|
# parser - the parser to use for generating AST's out of the given source
|
26
|
-
def initialize(code, description, parser
|
26
|
+
def initialize(code, description, parser: Parser::Ruby22)
|
27
27
|
@source = code
|
28
28
|
@description = description
|
29
29
|
@parser = parser
|
data/lib/reek/spec.rb
CHANGED
@@ -106,7 +106,7 @@ module Reek
|
|
106
106
|
# Returns +true+ if and only if the target source code contains smells.
|
107
107
|
#
|
108
108
|
def reek(configuration = Configuration::AppConfiguration.default)
|
109
|
-
ShouldReek.new configuration
|
109
|
+
ShouldReek.new(configuration: configuration)
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
data/lib/reek/tree_dresser.rb
CHANGED
@@ -7,23 +7,38 @@ module Reek
|
|
7
7
|
#
|
8
8
|
# @api private
|
9
9
|
class TreeDresser
|
10
|
-
def initialize(klass_map
|
10
|
+
def initialize(klass_map: AST::ASTNodeClassMap.new)
|
11
11
|
@klass_map = klass_map
|
12
12
|
end
|
13
13
|
|
14
14
|
# Recursively enhance an AST with type-dependent mixins, and comments.
|
15
15
|
#
|
16
16
|
# See {file:docs/How-reek-works-internally.md} for the big picture of how this works.
|
17
|
-
#
|
17
|
+
# Example:
|
18
|
+
# This
|
19
|
+
# class Klazz; def meth(argument); argument.call_me; end; end
|
20
|
+
# corresponds to this sexp:
|
21
|
+
# (class
|
22
|
+
# (const nil :Klazz) nil
|
23
|
+
# (def :meth
|
24
|
+
# (args
|
25
|
+
# (arg :argument))
|
26
|
+
# (send
|
27
|
+
# (lvar :argument) :call_me)))
|
28
|
+
# where every node is of type Parser::AST::Node.
|
29
|
+
# Passing this into `dress` will return the exact same structure, but this
|
30
|
+
# time the nodes will contain type-dependent mixins, e.g. this:
|
31
|
+
# (const nil :Klazz)
|
32
|
+
# will be of type Reek::AST::Node with Reek::AST::SexpExtensions::ConstNode mixed in.
|
18
33
|
# @param sexp [Parser::AST::Node] - the given sexp
|
19
34
|
# @param comment_map [Hash] - see the documentation for SourceCode#syntax_tree
|
20
35
|
# @param parent [Parser::AST::Node] - the parent sexp
|
21
36
|
#
|
22
37
|
# @return an instance of Reek::AST::Node with type-dependent sexp extensions mixed in.
|
23
|
-
def dress(sexp, comment_map, parent
|
38
|
+
def dress(sexp, comment_map, parent: nil)
|
24
39
|
return sexp unless sexp.is_a? ::Parser::AST::Node
|
25
40
|
type = sexp.type
|
26
|
-
children = sexp.children.map { |child| dress(child, comment_map, sexp) }
|
41
|
+
children = sexp.children.map { |child| dress(child, comment_map, parent: sexp) }
|
27
42
|
comments = comment_map[sexp]
|
28
43
|
klass_map.klass_for(type).new(type, children,
|
29
44
|
location: sexp.loc, comments: comments, parent: parent)
|
data/lib/reek/version.rb
CHANGED
data/spec/reek/ast/node_spec.rb
CHANGED
@@ -4,20 +4,20 @@ require_relative '../../../lib/reek/ast/node'
|
|
4
4
|
RSpec.describe Reek::AST::Node do
|
5
5
|
context 'format' do
|
6
6
|
it 'formats self' do
|
7
|
-
expect(
|
7
|
+
expect(sexp(:self).format_to_ruby).to eq('self')
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
11
|
context 'hash' do
|
12
12
|
it 'hashes equal for equal sexps' do
|
13
|
-
node1 =
|
14
|
-
node2 =
|
13
|
+
node1 = sexp(:def, :jim, sexp(:args), sexp(:send, sexp(:int, 4), :+, sexp(:send, nil, :fred)))
|
14
|
+
node2 = sexp(:def, :jim, sexp(:args), sexp(:send, sexp(:int, 4), :+, sexp(:send, nil, :fred)))
|
15
15
|
expect(node1.hash).to eq(node2.hash)
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'hashes diferent for diferent sexps' do
|
19
|
-
node1 =
|
20
|
-
node2 =
|
19
|
+
node1 = sexp(:def, :jim, sexp(:args), sexp(:send, sexp(:int, 4), :+, sexp(:send, nil, :fred)))
|
20
|
+
node2 = sexp(:def, :jim, sexp(:args), sexp(:send, sexp(:int, 3), :+, sexp(:send, nil, :fred)))
|
21
21
|
expect(node1.hash).not_to eq(node2.hash)
|
22
22
|
end
|
23
23
|
end
|
@@ -3,7 +3,7 @@ require_relative '../../../lib/reek/ast/sexp_extensions'
|
|
3
3
|
|
4
4
|
RSpec.describe Reek::AST::SexpExtensions::DefNode do
|
5
5
|
context 'with no parameters' do
|
6
|
-
let(:node) {
|
6
|
+
let(:node) { sexp(:def, :hello, sexp(:args)) }
|
7
7
|
|
8
8
|
it 'has no arg names' do
|
9
9
|
expect(node.arg_names).to eq []
|
@@ -24,8 +24,8 @@ RSpec.describe Reek::AST::SexpExtensions::DefNode do
|
|
24
24
|
|
25
25
|
context 'with 1 parameter' do
|
26
26
|
let(:node) do
|
27
|
-
|
28
|
-
|
27
|
+
sexp(:def, :hello,
|
28
|
+
sexp(:args, sexp(:arg, :param)))
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'has 1 arg name' do
|
@@ -47,10 +47,10 @@ RSpec.describe Reek::AST::SexpExtensions::DefNode do
|
|
47
47
|
|
48
48
|
context 'with a block parameter' do
|
49
49
|
let(:node) do
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
sexp(:def, :hello,
|
51
|
+
sexp(:args,
|
52
|
+
sexp(:arg, :param),
|
53
|
+
sexp(:blockarg, :blk)))
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'has 1 arg name' do
|
@@ -72,9 +72,9 @@ RSpec.describe Reek::AST::SexpExtensions::DefNode do
|
|
72
72
|
|
73
73
|
context 'with 1 defaulted parameter' do
|
74
74
|
let(:node) do
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
sexp(:def, :hello,
|
76
|
+
sexp(:args,
|
77
|
+
sexp(:optarg, :param, sexp(:array))))
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'has 1 arg name' do
|
@@ -96,23 +96,23 @@ RSpec.describe Reek::AST::SexpExtensions::DefNode do
|
|
96
96
|
|
97
97
|
context 'with a body with 2 statements' do
|
98
98
|
let(:node) do
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
99
|
+
sexp(:def, :hello, sexp(:args),
|
100
|
+
sexp(:begin,
|
101
|
+
sexp(:first),
|
102
|
+
sexp(:second)))
|
103
103
|
end
|
104
104
|
|
105
105
|
it 'has 2 body statements' do
|
106
|
-
expect(node.body).to eq
|
106
|
+
expect(node.body).to eq sexp(:begin, sexp(:first), sexp(:second))
|
107
107
|
end
|
108
108
|
|
109
109
|
it 'finds nodes in the body with #body_nodes' do
|
110
|
-
expect(node.body_nodes([:first])).to eq [
|
110
|
+
expect(node.body_nodes([:first])).to eq [sexp(:first)]
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
114
|
context 'with no body' do
|
115
|
-
let(:node) {
|
115
|
+
let(:node) { sexp(:def, :hello, sexp(:args), nil) }
|
116
116
|
|
117
117
|
it 'has a body that is nil' do
|
118
118
|
expect(node.body).to be_nil
|
@@ -126,7 +126,7 @@ end
|
|
126
126
|
|
127
127
|
RSpec.describe Reek::AST::SexpExtensions::DefsNode do
|
128
128
|
context 'with no parameters' do
|
129
|
-
let(:node) {
|
129
|
+
let(:node) { sexp(:defs, sexp(:lvar, :obj), :hello, sexp(:args)) }
|
130
130
|
|
131
131
|
it 'has no arg names' do
|
132
132
|
expect(node.arg_names).to eq []
|
@@ -147,8 +147,8 @@ RSpec.describe Reek::AST::SexpExtensions::DefsNode do
|
|
147
147
|
|
148
148
|
context 'with 1 parameter' do
|
149
149
|
let(:node) do
|
150
|
-
|
151
|
-
|
150
|
+
sexp(:defs, sexp(:lvar, :obj), :hello,
|
151
|
+
sexp(:args, sexp(:arg, :param)))
|
152
152
|
end
|
153
153
|
|
154
154
|
it 'has 1 arg name' do
|
@@ -170,10 +170,10 @@ RSpec.describe Reek::AST::SexpExtensions::DefsNode do
|
|
170
170
|
|
171
171
|
context 'with a block' do
|
172
172
|
let(:node) do
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
173
|
+
sexp(:defs, sexp(:lvar, :obj), :hello,
|
174
|
+
sexp(:args,
|
175
|
+
sexp(:arg, :param),
|
176
|
+
sexp(:blockarg, :blk)))
|
177
177
|
end
|
178
178
|
|
179
179
|
it 'has 1 arg name' do
|
@@ -195,9 +195,9 @@ RSpec.describe Reek::AST::SexpExtensions::DefsNode do
|
|
195
195
|
|
196
196
|
context 'with 1 defaulted parameter' do
|
197
197
|
let(:node) do
|
198
|
-
|
199
|
-
|
200
|
-
|
198
|
+
sexp(:defs, sexp(:lvar, :obj), :hello,
|
199
|
+
sexp(:args,
|
200
|
+
sexp(:optarg, :param, sexp(:array))))
|
201
201
|
end
|
202
202
|
|
203
203
|
it 'has 1 arg name' do
|
@@ -219,21 +219,21 @@ RSpec.describe Reek::AST::SexpExtensions::DefsNode do
|
|
219
219
|
|
220
220
|
context 'with a body with 2 statements' do
|
221
221
|
let(:node) do
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
222
|
+
sexp(:defs, sexp(:self), :hello, sexp(:args),
|
223
|
+
sexp(:begin,
|
224
|
+
sexp(:first),
|
225
|
+
sexp(:second)))
|
226
226
|
end
|
227
227
|
|
228
228
|
it 'has 2 body statements' do
|
229
|
-
expect(node.body).to eq
|
229
|
+
expect(node.body).to eq sexp(:begin, sexp(:first), sexp(:second))
|
230
230
|
end
|
231
231
|
end
|
232
232
|
end
|
233
233
|
|
234
234
|
RSpec.describe Reek::AST::SexpExtensions::SendNode do
|
235
235
|
context 'with no parameters' do
|
236
|
-
let(:node) {
|
236
|
+
let(:node) { sexp(:send, nil, :hello) }
|
237
237
|
|
238
238
|
it 'has no argument names' do
|
239
239
|
expect(node.arg_names).to eq []
|
@@ -241,7 +241,7 @@ RSpec.describe Reek::AST::SexpExtensions::SendNode do
|
|
241
241
|
end
|
242
242
|
|
243
243
|
context 'with 1 literal parameter' do
|
244
|
-
let(:node) {
|
244
|
+
let(:node) { sexp(:send, nil, :hello, sexp(:lit, :param)) }
|
245
245
|
|
246
246
|
it 'has 1 argument name' do
|
247
247
|
expect(node.arg_names).to eq [:param]
|
@@ -249,7 +249,7 @@ RSpec.describe Reek::AST::SexpExtensions::SendNode do
|
|
249
249
|
end
|
250
250
|
|
251
251
|
context 'with 2 literal parameters' do
|
252
|
-
let(:node) {
|
252
|
+
let(:node) { sexp(:send, nil, :hello, sexp(:lit, :x), sexp(:lit, :y)) }
|
253
253
|
|
254
254
|
it 'has 2 argument names' do
|
255
255
|
expect(node.arg_names).to eq [:x, :y]
|
@@ -259,7 +259,7 @@ end
|
|
259
259
|
|
260
260
|
RSpec.describe Reek::AST::SexpExtensions::BlockNode do
|
261
261
|
context 'with no parameters' do
|
262
|
-
let(:node) {
|
262
|
+
let(:node) { sexp(:block, sexp(:send, nil, :map), sexp(:args), nil) }
|
263
263
|
|
264
264
|
it 'has no parameter names' do
|
265
265
|
expect(node.parameter_names).to eq []
|
@@ -267,7 +267,7 @@ RSpec.describe Reek::AST::SexpExtensions::BlockNode do
|
|
267
267
|
end
|
268
268
|
|
269
269
|
context 'with 1 parameter' do
|
270
|
-
let(:node) {
|
270
|
+
let(:node) { sexp(:block, sexp(:send, nil, :map), sexp(:args, :param), nil) }
|
271
271
|
|
272
272
|
it 'has 1 parameter name' do
|
273
273
|
expect(node.parameter_names).to eq [:param]
|
@@ -275,7 +275,7 @@ RSpec.describe Reek::AST::SexpExtensions::BlockNode do
|
|
275
275
|
end
|
276
276
|
|
277
277
|
context 'with 2 parameters' do
|
278
|
-
let(:node) {
|
278
|
+
let(:node) { sexp(:block, sexp(:send, nil, :map), sexp(:args, :x, :y), nil) }
|
279
279
|
|
280
280
|
it 'has 2 parameter names' do
|
281
281
|
expect(node.parameter_names).to eq [:x, :y]
|
@@ -286,7 +286,7 @@ end
|
|
286
286
|
RSpec.describe Reek::AST::SexpExtensions::ModuleNode do
|
287
287
|
context 'with a simple name' do
|
288
288
|
subject do
|
289
|
-
mod =
|
289
|
+
mod = sexp(:module, :Fred, nil)
|
290
290
|
mod
|
291
291
|
end
|
292
292
|
|
@@ -309,7 +309,7 @@ RSpec.describe Reek::AST::SexpExtensions::ModuleNode do
|
|
309
309
|
|
310
310
|
context 'with a scoped name' do
|
311
311
|
subject do
|
312
|
-
|
312
|
+
sexp(:module, sexp(:const, sexp(:const, nil, :Foo), :Bar), nil)
|
313
313
|
end
|
314
314
|
|
315
315
|
it 'has the correct #name' do
|
@@ -333,7 +333,7 @@ end
|
|
333
333
|
RSpec.describe Reek::AST::SexpExtensions::CasgnNode do
|
334
334
|
context 'with single assignment' do
|
335
335
|
subject do
|
336
|
-
|
336
|
+
sexp(:casgn, nil, :Foo)
|
337
337
|
end
|
338
338
|
|
339
339
|
it 'does not define a module' do
|
@@ -4,30 +4,30 @@ require_relative '../../../lib/reek/ast/sexp_formatter'
|
|
4
4
|
RSpec.describe Reek::AST::SexpFormatter do
|
5
5
|
describe '::format' do
|
6
6
|
it 'formats a simple s-expression' do
|
7
|
-
result = described_class.format
|
7
|
+
result = described_class.format sexp(:lvar, :foo)
|
8
8
|
expect(result).to eq('foo')
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'formats a more complex s-expression' do
|
12
|
-
ast =
|
12
|
+
ast = sexp(:send, nil, :foo, sexp(:lvar, :bar))
|
13
13
|
result = described_class.format(ast)
|
14
14
|
expect(result).to eq('foo(bar)')
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'reduces very large ASTs to a single line' do
|
18
|
-
ast =
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
ast = sexp(:if,
|
19
|
+
sexp(:send, nil, :foo),
|
20
|
+
sexp(:send, nil, :bar),
|
21
|
+
sexp(:begin,
|
22
|
+
sexp(:send, nil, :baz),
|
23
|
+
sexp(:send, nil, :qux)))
|
24
24
|
result = described_class.format ast
|
25
25
|
|
26
26
|
expect(result).to eq 'if foo ... end'
|
27
27
|
end
|
28
28
|
|
29
29
|
it "doesn't reduce two-line ASTs" do
|
30
|
-
ast =
|
30
|
+
ast = sexp(:def, 'my_method', sexp(:args))
|
31
31
|
result = described_class.format ast
|
32
32
|
expect(result).to eq 'def my_method; end'
|
33
33
|
end
|
@@ -78,7 +78,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
78
78
|
|
79
79
|
it "yields the module's full AST" do
|
80
80
|
ctx.each_node(:module, []) do |exp|
|
81
|
-
expect(exp).to eq(
|
81
|
+
expect(exp).to eq(sexp(:module, sexp(:const, nil, :Emptiness), nil))
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -105,11 +105,11 @@ RSpec.describe Reek::Context::CodeContext do
|
|
105
105
|
|
106
106
|
it "yields the module's full AST" do
|
107
107
|
ctx.each_node(:module, []) do |exp|
|
108
|
-
expect(exp).to eq
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
expect(exp).to eq sexp(:module,
|
109
|
+
sexp(:const, nil, :Loneliness),
|
110
|
+
sexp(:def, :calloo,
|
111
|
+
sexp(:args),
|
112
|
+
sexp(:send, nil, :puts, sexp(:str, 'hello'))))
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
@@ -209,7 +209,7 @@ RSpec.describe Reek::Context::CodeContext do
|
|
209
209
|
|
210
210
|
it 'sets visibility on subsequent child contexts' do
|
211
211
|
context.append_child_context first_child
|
212
|
-
context.track_visibility :private
|
212
|
+
context.track_visibility :private, []
|
213
213
|
context.append_child_context second_child
|
214
214
|
expect(first_child.visibility).to eq :public
|
215
215
|
expect(second_child.visibility).to eq :private
|
@@ -23,27 +23,27 @@ RSpec.describe Reek::Context::MethodContext do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
describe '#envious_receivers' do
|
26
|
-
let(:exp) {
|
26
|
+
let(:exp) { sexp(:def, :foo, sexp(:args, sexp(:arg, :bar)), nil) }
|
27
27
|
|
28
28
|
it 'should ignore ivars as refs to self' do
|
29
|
-
method_context.record_call_to
|
29
|
+
method_context.record_call_to sexp(:send, sexp(:ivar, :@cow), :feed_to)
|
30
30
|
expect(method_context.envious_receivers).to be_empty
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should ignore explicit calls to self' do
|
34
34
|
method_context.refs.record_reference_to :other
|
35
|
-
method_context.record_call_to
|
35
|
+
method_context.record_call_to sexp(:send, sexp(:self), :thing)
|
36
36
|
expect(method_context.envious_receivers).to be_empty
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'should ignore implicit calls to self' do
|
40
|
-
method_context.record_call_to
|
41
|
-
method_context.record_call_to
|
40
|
+
method_context.record_call_to sexp(:send, sexp(:lvar, :text), :each, sexp(:arglist))
|
41
|
+
method_context.record_call_to sexp(:send, nil, :shelve, sexp(:arglist))
|
42
42
|
expect(method_context.envious_receivers).to be_empty
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'should record envious calls' do
|
46
|
-
method_context.record_call_to
|
46
|
+
method_context.record_call_to sexp(:send, sexp(:lvar, :bar), :baz)
|
47
47
|
expect(method_context.envious_receivers).to include(:bar)
|
48
48
|
end
|
49
49
|
end
|
@@ -66,7 +66,7 @@ RSpec.describe Reek::Context::MethodContext do
|
|
66
66
|
let(:defaults) { assignments_from('def meth(arga, argb=456, &blk) end') }
|
67
67
|
|
68
68
|
it 'returns the param-value pair' do
|
69
|
-
expect(defaults[0]).to eq [:argb,
|
69
|
+
expect(defaults[0]).to eq [:argb, sexp(:int, 456)]
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'returns the nothing else' do
|
@@ -80,8 +80,8 @@ RSpec.describe Reek::Context::MethodContext do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'returns both param-value pairs' do
|
83
|
-
expect(defaults[0]).to eq [:arga,
|
84
|
-
expect(defaults[1]).to eq [:argb,
|
83
|
+
expect(defaults[0]).to eq [:arga, sexp(:int, 123)]
|
84
|
+
expect(defaults[1]).to eq [:argb, sexp(:int, 456)]
|
85
85
|
end
|
86
86
|
|
87
87
|
it 'returns nothing else' do
|
@@ -3,13 +3,13 @@ require_relative '../../../lib/reek/context/singleton_method_context'
|
|
3
3
|
|
4
4
|
RSpec.describe Reek::Context::SingletonMethodContext do
|
5
5
|
let(:smc) do
|
6
|
-
sexp =
|
6
|
+
sexp = sexp(:def, :foo, sexp(:args, sexp(:arg, :bar)), nil)
|
7
7
|
Reek::Context::SingletonMethodContext.new(nil, sexp)
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '#envious_receivers' do
|
11
11
|
it 'should not record envious calls' do
|
12
|
-
smc.record_call_to
|
12
|
+
smc.record_call_to sexp(:send, sexp(:lvar, :bar), :baz)
|
13
13
|
expect(smc.envious_receivers).to be_empty
|
14
14
|
end
|
15
15
|
end
|
@@ -16,7 +16,8 @@ RSpec.describe Reek::Report::HTMLReport do
|
|
16
16
|
it 'has the text 0 total warnings' do
|
17
17
|
tempfile = Tempfile.new(['Reek::Report::HTMLReport.', '.html'])
|
18
18
|
response = "HTML file saved\n"
|
19
|
-
expect { instance.show tempfile.path }.
|
19
|
+
expect { instance.show(target_path: tempfile.path) }.
|
20
|
+
to output(response).to_stdout
|
20
21
|
expect(tempfile.read).to include('0 total warnings')
|
21
22
|
end
|
22
23
|
end
|
@@ -12,12 +12,12 @@ RSpec.describe Reek::Smells::ClassVariable do
|
|
12
12
|
|
13
13
|
context 'with no class variables' do
|
14
14
|
it 'records nothing in the class' do
|
15
|
-
exp =
|
15
|
+
exp = sexp(:class, :Fred)
|
16
16
|
expect(detector.examine_context(Reek::Context::CodeContext.new(nil, exp))).to be_empty
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'records nothing in the module' do
|
20
|
-
exp =
|
20
|
+
exp = sexp(:module, :Fred)
|
21
21
|
expect(detector.examine_context(Reek::Context::CodeContext.new(nil, exp))).to be_empty
|
22
22
|
end
|
23
23
|
end
|
@@ -22,6 +22,11 @@ RSpec.describe Reek::Smells::NestedIterators do
|
|
22
22
|
expect(src).to reek_of(:NestedIterators)
|
23
23
|
end
|
24
24
|
|
25
|
+
it 'should not report nested iterators for Object#tap' do
|
26
|
+
src = 'def do_stuff(*params); [].tap {|list| params.map {|param| list << (param + param)} } end'
|
27
|
+
expect(src).not_to reek_of(:NestedIterators)
|
28
|
+
end
|
29
|
+
|
25
30
|
it 'should not report method with successive iterators' do
|
26
31
|
src = <<-EOS
|
27
32
|
def bad(fred)
|
@@ -30,7 +30,7 @@ RSpec.describe Reek::Source::SourceCode do
|
|
30
30
|
let(:source_name) { 'Test source' }
|
31
31
|
let(:error_message) { 'Error message' }
|
32
32
|
let(:parser) { double('parser') }
|
33
|
-
let(:src) { Reek::Source::SourceCode.new('', source_name, parser) }
|
33
|
+
let(:src) { Reek::Source::SourceCode.new('', source_name, parser: parser) }
|
34
34
|
|
35
35
|
before { $stderr = catcher }
|
36
36
|
|
@@ -46,7 +46,7 @@ RSpec.describe Reek::Spec::ShouldReek do
|
|
46
46
|
context 'matcher without masking' do
|
47
47
|
let(:path) { SAMPLES_PATH.join('clean_due_to_masking/masked.reek') }
|
48
48
|
let(:configuration) { test_configuration_for(path) }
|
49
|
-
let(:matcher) { Reek::Spec::ShouldReek.new configuration }
|
49
|
+
let(:matcher) { Reek::Spec::ShouldReek.new(configuration: configuration) }
|
50
50
|
let(:masked_file) { SAMPLES_PATH.join('clean_due_to_masking/dirty_one.rb') }
|
51
51
|
|
52
52
|
it 'masks smells using the relevant configuration' do
|
@@ -1,16 +1,50 @@
|
|
1
|
+
require_relative '../../lib/reek/cli/silencer'
|
2
|
+
Reek::CLI::Silencer.silently do
|
3
|
+
require 'parser/ruby22'
|
4
|
+
end
|
5
|
+
|
1
6
|
require_relative '../spec_helper'
|
2
7
|
require_relative '../../lib/reek/tree_dresser'
|
3
8
|
|
4
9
|
RSpec.describe Reek::TreeDresser do
|
5
|
-
let(:ifnode) { ::Parser::AST::Node.new(:if) }
|
6
|
-
let(:sendnode) { ::Parser::AST::Node.new(:send) }
|
7
10
|
let(:dresser) { described_class.new }
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
let(:sexp) do
|
12
|
+
Parser::Ruby22.parse('class Klazz; def meth(argument); argument.call_me; end; end')
|
13
|
+
end
|
14
|
+
let(:dressed_ast) do
|
15
|
+
# The dressed AST looks like this:
|
16
|
+
# (class
|
17
|
+
# (const nil :Klazz) nil
|
18
|
+
# (def :meth
|
19
|
+
# (args
|
20
|
+
# (arg :argument))
|
21
|
+
# (send
|
22
|
+
# (lvar :argument) :call_me)))
|
23
|
+
dresser.dress(sexp, {})
|
11
24
|
end
|
25
|
+
let(:const_node) { dressed_ast.children.first }
|
26
|
+
let(:def_node) { dressed_ast.children.last }
|
27
|
+
let(:args_node) { def_node.children[1] }
|
28
|
+
let(:send_node) { def_node.children[2] }
|
29
|
+
|
30
|
+
context 'dresses the given sexp' do
|
31
|
+
it 'dresses `const` nodes properly' do
|
32
|
+
expect(const_node).to be_a Reek::AST::SexpExtensions::ConstNode
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'dresses `def` nodes properly' do
|
36
|
+
expect(def_node).to be_a Reek::AST::SexpExtensions::DefNode
|
37
|
+
expect(def_node).to be_a Reek::AST::SexpExtensions::SingletonMethod
|
38
|
+
expect(def_node).to be_a Reek::AST::SexpExtensions::MethodNodeBase
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'dresses `args` nodes properly' do
|
42
|
+
expect(args_node).to be_a Reek::AST::SexpExtensions::ArgsNode
|
43
|
+
expect(args_node).to be_a Reek::AST::SexpExtensions::NestedAssignables
|
44
|
+
end
|
12
45
|
|
13
|
-
|
14
|
-
|
46
|
+
it 'dresses `send` nodes properly' do
|
47
|
+
expect(send_node).to be_a Reek::AST::SexpExtensions::SendNode
|
48
|
+
end
|
15
49
|
end
|
16
50
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,6 @@ require_relative '../lib/reek'
|
|
3
3
|
require_relative '../lib/reek/spec'
|
4
4
|
require_relative '../lib/reek/ast/ast_node_class_map'
|
5
5
|
require_relative '../lib/reek/configuration/app_configuration'
|
6
|
-
require 'ostruct'
|
7
6
|
|
8
7
|
Reek::CLI::Silencer.silently do
|
9
8
|
require 'factory_girl'
|
@@ -35,17 +34,12 @@ module Helpers
|
|
35
34
|
end
|
36
35
|
|
37
36
|
# :reek:UncommunicativeMethodName
|
38
|
-
def
|
37
|
+
def sexp(type, *children)
|
39
38
|
@klass_map ||= Reek::AST::ASTNodeClassMap.new
|
40
39
|
@klass_map.klass_for(type).new(type, children)
|
41
40
|
end
|
42
|
-
|
43
|
-
def ast(*args)
|
44
|
-
s(*args)
|
45
|
-
end
|
46
41
|
end
|
47
42
|
|
48
|
-
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
49
43
|
RSpec.configure do |config|
|
50
44
|
config.filter_run :focus
|
51
45
|
config.run_all_when_everything_filtered = true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rutherford
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-
|
14
|
+
date: 2015-09-03 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: parser
|