reek 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +5 -0
  3. data/README.md +13 -2
  4. data/Rakefile +2 -1
  5. data/features/command_line_interface/options.feature +2 -3
  6. data/features/command_line_interface/smell_selection.feature +0 -1
  7. data/features/command_line_interface/smells_count.feature +0 -2
  8. data/features/command_line_interface/stdin.feature +3 -10
  9. data/features/configuration_files/masking_smells.feature +1 -5
  10. data/features/configuration_files/overrides_defaults.feature +0 -1
  11. data/features/rake_task/rake_task.feature +1 -4
  12. data/features/reports/json.feature +73 -0
  13. data/features/reports/reports.feature +0 -3
  14. data/features/reports/yaml.feature +0 -1
  15. data/features/ruby_api/api.feature +0 -1
  16. data/features/samples.feature +0 -4
  17. data/features/step_definitions/reek_steps.rb +14 -4
  18. data/features/support/env.rb +3 -0
  19. data/lib/reek/cli/option_interpreter.rb +2 -0
  20. data/lib/reek/cli/options.rb +3 -3
  21. data/lib/reek/cli/report/formatter.rb +1 -1
  22. data/lib/reek/cli/report/location_formatter.rb +11 -0
  23. data/lib/reek/cli/report/report.rb +11 -2
  24. data/lib/reek/core/code_context.rb +49 -10
  25. data/lib/reek/core/sniffer.rb +2 -2
  26. data/lib/reek/core/{code_parser.rb → tree_walker.rb} +16 -7
  27. data/lib/reek/examiner.rb +0 -39
  28. data/lib/reek/smells.rb +3 -25
  29. data/lib/reek/smells/feature_envy.rb +0 -2
  30. data/lib/reek/smells/smell_detector.rb +0 -6
  31. data/lib/reek/source/sexp_extensions.rb +17 -6
  32. data/lib/reek/source/sexp_node.rb +1 -1
  33. data/lib/reek/spec.rb +66 -0
  34. data/lib/reek/spec/should_reek.rb +0 -6
  35. data/lib/reek/spec/should_reek_of.rb +0 -49
  36. data/lib/reek/spec/should_reek_only_of.rb +0 -11
  37. data/lib/reek/version.rb +6 -1
  38. data/reek.gemspec +3 -2
  39. data/spec/reek/cli/json_report_spec.rb +20 -0
  40. data/spec/reek/core/code_context_spec.rb +6 -0
  41. data/spec/reek/core/smell_configuration_spec.rb +3 -3
  42. data/spec/reek/core/{code_parser_spec.rb → tree_walker_spec.rb} +4 -4
  43. data/spec/reek/examiner_spec.rb +0 -19
  44. data/spec/reek/smells/attribute_spec.rb +6 -9
  45. data/spec/reek/smells/boolean_parameter_spec.rb +13 -15
  46. data/spec/reek/smells/class_variable_spec.rb +17 -17
  47. data/spec/reek/smells/control_parameter_spec.rb +44 -46
  48. data/spec/reek/smells/data_clump_spec.rb +73 -70
  49. data/spec/reek/smells/duplicate_method_call_spec.rb +39 -37
  50. data/spec/reek/smells/feature_envy_spec.rb +53 -57
  51. data/spec/reek/smells/irresponsible_module_spec.rb +12 -11
  52. data/spec/reek/smells/long_parameter_list_spec.rb +33 -26
  53. data/spec/reek/smells/long_yield_list_spec.rb +15 -19
  54. data/spec/reek/smells/module_initialize_spec.rb +4 -6
  55. data/spec/reek/smells/nested_iterators_spec.rb +28 -28
  56. data/spec/reek/smells/nil_check_spec.rb +18 -20
  57. data/spec/reek/smells/prima_donna_method_spec.rb +6 -9
  58. data/spec/reek/smells/repeated_conditional_spec.rb +41 -43
  59. data/spec/reek/smells/too_many_instance_variables_spec.rb +6 -11
  60. data/spec/reek/smells/too_many_methods_spec.rb +44 -61
  61. data/spec/reek/smells/too_many_statements_spec.rb +14 -41
  62. data/spec/reek/smells/uncommunicative_method_name_spec.rb +6 -11
  63. data/spec/reek/smells/uncommunicative_module_name_spec.rb +10 -14
  64. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +15 -16
  65. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +33 -36
  66. data/spec/reek/smells/unused_parameters_spec.rb +16 -19
  67. data/spec/reek/smells/utility_function_spec.rb +7 -10
  68. metadata +22 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e9938a6d72e1e64ab84f0cbfc67d43574a0d9b8
4
- data.tar.gz: 102ac522a9e2df22fbbec630f09d97174e4e5bd0
3
+ metadata.gz: f4119a0e66c059ea4a0d565bfab3ecfaeef3c722
4
+ data.tar.gz: 60149f1e3dda3e9f1b9f1e03f2287817ab9715ce
5
5
  SHA512:
6
- metadata.gz: c7b67443588cd094db2a47cd4fddf96190ea87c4c44e68fe6620f86638346e1dc38ad9e84941e6939360765762738b3fa5902289db52f2fa1ef1e78066b412ef
7
- data.tar.gz: 16a5d7d2c2750e4a7d1324ca9bb6076fb3caad8eb929fb319dff712e895c6ffe73420e4f914317a5981f26300dc3fe5f1c926e36e69dd1ed7b1bbed0214ff2a8
6
+ metadata.gz: de5e40087670fc35f74a341f9e50c477aa1deaeb914abe7466afe4ce53efaf9fb38633b814424cc50cc20aa08e1563f1e65169d159bc29b6e720f012d11b628b
7
+ data.tar.gz: ed3e2bddfbc5e369f1079da7e1a7684dc6ab28d1ad6d64625541587ec47c0173b7596de15ac4b26737401a6cb0d9ec82a8c0696cd88603e57772530254ead51f
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ == 2.0.1
2
+
3
+ * (leonelgalan) Add support for json reports
4
+ * (chastell) Escape Regexp-like Strings on CodeContext matches (Bug https://github.com/troessner/reek/pull/397)
5
+
1
6
  == 2.0.0
2
7
 
3
8
  * (troessner) Revise, improve & refactor our Rspec matcher and remove smell_of
data/README.md CHANGED
@@ -209,8 +209,9 @@ If you don't feel like getting your hands dirty with code there are still other
209
209
  `reek` supports 3 output formats:
210
210
 
211
211
  * plain text (default)
212
- * html (-H, --html)
213
- * yaml (-y, --yaml)
212
+ * html (`--format html`)
213
+ * yaml (`--format yaml`)
214
+ * json (`--format json`)
214
215
 
215
216
  ## Additional resources
216
217
 
@@ -229,3 +230,13 @@ Colorful output for `reek`: [Preek](https://github.com/joenas/preek) (also with
229
230
 
230
231
  * [Stack Overflow](http://stackoverflow.com/questions/tagged/reek)
231
232
  * [RDoc](http://rdoc.info/projects/troessner/reek)
233
+
234
+ ## Contributors
235
+
236
+ A non exhaustive list:
237
+
238
+ * Kevin Rutherford
239
+ * Matijs van Zuijlen
240
+ * Andrew Wagner
241
+ * Gilles Leblanc
242
+ * Timo Rößner
data/Rakefile CHANGED
@@ -3,4 +3,5 @@ require 'bundler/gem_tasks'
3
3
 
4
4
  Dir['tasks/**/*.rake'].each { |t| load t }
5
5
 
6
- task default: [:test, :rubocop]
6
+ task default: :test
7
+ task default: :rubocop unless RUBY_ENGINE == 'rbx'
@@ -1,4 +1,3 @@
1
- @options
2
1
  Feature: Reek can be controlled using command-line options
3
2
  In order to change reek's default behaviour
4
3
  As a developer
@@ -8,7 +7,7 @@ Feature: Reek can be controlled using command-line options
8
7
  When I run reek --no-such-option
9
8
  Then the exit status indicates an error
10
9
  And it reports the error "Error: invalid option: --no-such-option"
11
- And stdout equals ""
10
+ And there is no output on stdout
12
11
 
13
12
  Scenario: display the current version number
14
13
  When I run reek --version
@@ -39,6 +38,7 @@ Feature: Reek can be controlled using command-line options
39
38
  html
40
39
  text (default)
41
40
  yaml
41
+ json
42
42
 
43
43
  Text format options:
44
44
  --[no-]color Use colors for the output (this is the default)
@@ -53,5 +53,4 @@ Feature: Reek can be controlled using command-line options
53
53
  Utility options:
54
54
  -h, --help Show this message
55
55
  -v, --version Show version
56
-
57
56
  """
@@ -15,5 +15,4 @@ Feature: Smell selection
15
15
  Dirty#a calls @s.title 2 times (DuplicateMethodCall)
16
16
  Dirty#a calls puts(@s.title) 2 times (DuplicateMethodCall)
17
17
  4 total warnings
18
-
19
18
  """
@@ -1,4 +1,3 @@
1
- @smells_count
2
1
  Feature: Reports total number of code smells
3
2
  In order to monitor the total number of smells
4
3
  Reek outputs the total number of smells among all files inspected.
@@ -44,6 +43,5 @@ Feature: Reports total number of code smells
44
43
  Then it succeeds
45
44
  And it reports:
46
45
  """
47
-
48
46
  0 total warnings
49
47
  """
@@ -1,4 +1,3 @@
1
- @stdin
2
1
  Feature: Reek reads from $stdin when no files are given
3
2
  In order to use reek with pipelines
4
3
  As a developer
@@ -7,14 +6,12 @@ Feature: Reek reads from $stdin when no files are given
7
6
  Scenario: return zero status with no smells
8
7
  When I pass "def simple() @fred = 3 end" to reek
9
8
  Then it succeeds
10
- And it reports:
11
- """
12
- """
9
+ And it reports nothing
13
10
 
14
11
  Scenario: outputs nothing on empty stdin
15
12
  When I pass "" to reek
16
13
  Then it succeeds
17
- And stdout equals ""
14
+ And it reports nothing
18
15
 
19
16
  Scenario: outputs header only on empty stdin in verbose mode
20
17
  When I pass "" to reek -V
@@ -22,7 +19,6 @@ Feature: Reek reads from $stdin when no files are given
22
19
  And it reports:
23
20
  """
24
21
  $stdin -- 0 warnings
25
-
26
22
  """
27
23
 
28
24
  Scenario: return non-zero status when there are smells
@@ -34,13 +30,10 @@ Feature: Reek reads from $stdin when no files are given
34
30
  [1]:Turn has no descriptive comment (IrresponsibleModule)
35
31
  [1]:Turn has the variable name '@x' (UncommunicativeVariableName)
36
32
  [1]:Turn#y has the name 'y' (UncommunicativeMethodName)
37
-
38
33
  """
39
34
 
40
- @stderr
41
35
  Scenario: syntax error causes the source to be ignored
42
36
  When I pass "def incomplete" to reek
43
37
  Then it reports a parsing error
44
38
  Then it succeeds
45
- And stdout equals ""
46
-
39
+ And it reports nothing
@@ -1,4 +1,3 @@
1
- @masking
2
1
  Feature: Masking smells using config files
3
2
  In order to keep my reports meaningful
4
3
  As a developer
@@ -23,9 +22,7 @@ Feature: Masking smells using config files
23
22
  When I run reek -c spec/samples/corrupt_config_file/corrupt.reek spec/samples/corrupt_config_file
24
23
  Then it reports the error 'Error: Invalid configuration file "corrupt.reek" -- Not a hash'
25
24
  And the exit status indicates an error
26
- And it reports:
27
- """
28
- """
25
+ And it reports nothing
29
26
 
30
27
  Scenario: missing source file is an error
31
28
  When I run reek spec/samples/missing_source_file/dirty.rb
@@ -65,7 +62,6 @@ Feature: Masking smells using config files
65
62
  [5]:Dirty#a contains iterators nested 2 deep (NestedIterators)
66
63
  """
67
64
 
68
- @comments
69
65
  Scenario: provide extra masking inline in comments
70
66
  When I run reek -c spec/samples/inline_config/masked.reek spec/samples/inline_config
71
67
  Then the exit status indicates smells
@@ -1,4 +1,3 @@
1
- @overrides_defaults
2
1
  Feature: Overriding current rules by specifying new configuration values
3
2
  In order to customize Reek to suit my needs
4
3
  As a developer
@@ -1,4 +1,3 @@
1
- @rake
2
1
  Feature: Reek can be driven through its Task
3
2
  Reek provides an easy way to integrate its use into Rakefiles,
4
3
  via the Task class. These scenarios test its various options.
@@ -79,6 +78,4 @@ Feature: Reek can be driven through its Task
79
78
  end
80
79
  """
81
80
  Then it succeeds
82
- And it reports:
83
- """
84
- """
81
+ And it reports nothing
@@ -0,0 +1,73 @@
1
+ Feature: Report smells using simple JSON layout
2
+ In order to parse reek's output simply and consistently, simply
3
+ output a list of smells in JSON.
4
+
5
+ Scenario: output is empty when there are no smells
6
+ When I run reek --format json spec/samples/three_clean_files
7
+ Then it succeeds
8
+ And it reports this JSON:
9
+ """
10
+ []
11
+ """
12
+
13
+ Scenario: Indicate smells and print them as JSON when using files
14
+ When I run reek --format json spec/samples/standard_smelly/minimal_dirty.rb
15
+ Then the exit status indicates smells
16
+ And it reports this JSON:
17
+ """
18
+ [
19
+ {
20
+ "smell_category": "IrresponsibleModule",
21
+ "smell_type": "IrresponsibleModule",
22
+ "source": "spec/samples/standard_smelly/minimal_dirty.rb",
23
+ "context": "C",
24
+ "lines": [
25
+ 1
26
+ ],
27
+ "message": "has no descriptive comment",
28
+ "name": "C"
29
+ },
30
+ {
31
+ "smell_category": "UncommunicativeName",
32
+ "smell_type": "UncommunicativeModuleName",
33
+ "source": "spec/samples/standard_smelly/minimal_dirty.rb",
34
+ "context": "C",
35
+ "lines": [
36
+ 1
37
+ ],
38
+ "message": "has the name 'C'",
39
+ "name": "C"
40
+ },
41
+ {
42
+ "smell_category": "UncommunicativeName",
43
+ "smell_type": "UncommunicativeMethodName",
44
+ "source": "spec/samples/standard_smelly/minimal_dirty.rb",
45
+ "context": "C#m",
46
+ "lines": [
47
+ 2
48
+ ],
49
+ "message": "has the name 'm'",
50
+ "name": "m"
51
+ }
52
+ ]
53
+ """
54
+
55
+ Scenario: Indicate smells and print them as JSON when using STDIN
56
+ When I pass "class Turn; end" to reek --format json
57
+ Then the exit status indicates smells
58
+ And it reports this JSON:
59
+ """
60
+ [
61
+ {
62
+ "smell_category": "IrresponsibleModule",
63
+ "smell_type": "IrresponsibleModule",
64
+ "source": "$stdin",
65
+ "context": "Turn",
66
+ "lines": [
67
+ 1
68
+ ],
69
+ "message": "has no descriptive comment",
70
+ "name": "Turn"
71
+ }
72
+ ]
73
+ """
@@ -1,4 +1,3 @@
1
- @reports
2
1
  Feature: Correctly formatted reports
3
2
  In order to get the most out of reek
4
3
  As a developer
@@ -87,7 +86,6 @@ Feature: Correctly formatted reports
87
86
  Then it succeeds
88
87
  And it reports:
89
88
  """
90
-
91
89
  0 total warnings
92
90
  """
93
91
 
@@ -117,7 +115,6 @@ Feature: Correctly formatted reports
117
115
  Then it succeeds
118
116
  And it reports:
119
117
  """
120
-
121
118
  0 total warnings
122
119
  """
123
120
 
@@ -1,4 +1,3 @@
1
- @yaml
2
1
  Feature: Report smells using simple YAML layout
3
2
  In order to parse reek's output simply and consistently, simply
4
3
  output a list of smells in Yaml.
@@ -1,4 +1,3 @@
1
- @masking
2
1
  Feature: The Reek API maintains backwards compatibility
3
2
  In order to use Reek without fuss
4
3
  As a developer
@@ -1,10 +1,8 @@
1
- @samples
2
1
  Feature: Basic smell detection
3
2
  In order to write better software
4
3
  As a developer
5
4
  I want to detect the smells in my Ruby code
6
5
 
7
- @inline
8
6
  Scenario: Correct smells from inline.rb
9
7
  When I run reek --no-line-numbers spec/samples/inline.rb
10
8
  Then the exit status indicates smells
@@ -282,7 +280,6 @@ Feature: Basic smell detection
282
280
  RedCloth#to_html has approx 26 statements (TooManyStatements)
283
281
  """
284
282
 
285
- @ruby20
286
283
  Scenario: Correct smells from a source file with Ruby 2.0 specific syntax
287
284
  When I run reek spec/samples/ruby20_syntax.rb
288
285
  Then the exit status indicates smells
@@ -292,7 +289,6 @@ Feature: Basic smell detection
292
289
  [1]:SomeClass has no descriptive comment (IrresponsibleModule)
293
290
  """
294
291
 
295
- @ruby21
296
292
  Scenario: Correct smells from a source file with Ruby 2.1 specific syntax
297
293
  When I run reek spec/samples/ruby21_syntax.rb
298
294
  Then the exit status indicates smells
@@ -10,8 +10,12 @@ When /^I run rake (\w*) with:$/ do |name, task_def|
10
10
  rake(name, task_def)
11
11
  end
12
12
 
13
- Then /^stdout equals "([^\"]*)"$/ do |report|
14
- expect(@last_stdout).to eq report
13
+ Then /^it reports nothing$/ do
14
+ expect(@last_stdout).to eq ''
15
+ end
16
+
17
+ Then /^there is no output on stdout$/ do
18
+ expect(@last_stdout).to eq ''
15
19
  end
16
20
 
17
21
  Then /^stdout includes "(.*)"$/ do |text|
@@ -31,7 +35,7 @@ Then /^the exit status indicates smells$/ do
31
35
  end
32
36
 
33
37
  Then /^it reports:$/ do |report|
34
- expect(@last_stdout.chomp).to eq report.chomp
38
+ expect(@last_stdout).to eq "#{report}\n"
35
39
  end
36
40
 
37
41
  Then /^it reports this yaml:$/ do |expected_yaml|
@@ -40,6 +44,12 @@ Then /^it reports this yaml:$/ do |expected_yaml|
40
44
  expect(actual_warnings).to eq expected_warnings
41
45
  end
42
46
 
47
+ Then /^it reports this JSON:$/ do |expected_json|
48
+ expected_warnings = JSON.parse(expected_json.chomp)
49
+ actual_warnings = JSON.parse(@last_stdout)
50
+ expect(actual_warnings).to eq expected_warnings
51
+ end
52
+
43
53
  Then /^stderr reports:$/ do |report|
44
54
  expect(@last_stderr).to eq report
45
55
  end
@@ -65,7 +75,7 @@ Then /^it should indicate the line numbers of those smells$/ do
65
75
  end
66
76
 
67
77
  Then /^it reports the current version$/ do
68
- expect(@last_stdout).to eq "reek #{Reek::VERSION}\n"
78
+ expect(@last_stdout).to eq "reek #{Reek::Version::STRING}\n"
69
79
  end
70
80
 
71
81
  Given(/^"(.*?)" exists in the working directory$/) do |path|
@@ -9,6 +9,9 @@ begin
9
9
  rescue LoadError # rubocop:disable Lint/HandleExceptions
10
10
  end
11
11
 
12
+ #
13
+ # Provides runner methods used in the cucumber steps.
14
+ #
12
15
  class ReekWorld
13
16
  def run(cmd)
14
17
  stderr_file = Tempfile.new('reek-world')
@@ -34,6 +34,8 @@ module Reek
34
34
  case @options.report_format
35
35
  when :yaml
36
36
  Report::YamlReport
37
+ when :json
38
+ Report::JsonReport
37
39
  when :html
38
40
  Report::HtmlReport
39
41
  else # :text
@@ -52,9 +52,9 @@ module Reek
52
52
  def set_alternative_formatter_options
53
53
  @parser.separator "\nReport format:"
54
54
  @parser.on(
55
- '-f', '--format FORMAT', [:html, :text, :yaml],
55
+ '-f', '--format FORMAT', [:html, :text, :yaml, :json],
56
56
  'Report smells in the given format:',
57
- ' html', ' text (default)', ' yaml'
57
+ ' html', ' text (default)', ' yaml', ' json'
58
58
  ) do |opt|
59
59
  @options.report_format = opt
60
60
  end
@@ -122,7 +122,7 @@ module Reek
122
122
  exit
123
123
  end
124
124
  @parser.on_tail('-v', '--version', 'Show version') do
125
- puts "#{@parser.program_name} #{Reek::VERSION}\n"
125
+ puts "#{@parser.program_name} #{Reek::Version::STRING}\n"
126
126
  exit
127
127
  end
128
128
  end
@@ -52,7 +52,7 @@ module Reek
52
52
 
53
53
  def format(warning)
54
54
  "#{super} " \
55
- "[#{explanatory_link(warning)}]"
55
+ "[#{explanatory_link(warning)}]"
56
56
  end
57
57
 
58
58
  def explanatory_link(warning)
@@ -1,18 +1,29 @@
1
1
  module Reek
2
2
  module Cli
3
3
  module Report
4
+ #
5
+ # Formats the location of a warning as an empty string.
6
+ #
4
7
  module BlankLocationFormatter
5
8
  def self.format(_warning)
6
9
  ''
7
10
  end
8
11
  end
9
12
 
13
+ #
14
+ # Formats the location of a warning as an array of line numbers.
15
+ #
10
16
  module DefaultLocationFormatter
11
17
  def self.format(warning)
12
18
  "#{warning.lines.inspect}:"
13
19
  end
14
20
  end
15
21
 
22
+ #
23
+ # Formats the location of a warning as a combination of source file name
24
+ # and line number. In this format, it is not possible to show more than
25
+ # one line number, so the first number is displayed.
26
+ #
16
27
  module SingleLineLocationFormatter
17
28
  def self.format(warning)
18
29
  "#{warning.source}:#{warning.lines.first}: "