reek 1.3.5 → 1.3.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ad832e1c2e46ca1fd1789a92f7b8b30854ff2215
4
- data.tar.gz: 800911908bdc3111d76ff930e161a7d6f87fecf1
3
+ metadata.gz: cd6196b99429388642049ac970d159ca81066a08
4
+ data.tar.gz: 45ec008b56f8a42ca8edeaa9951ecc8b03fd5d7c
5
5
  SHA512:
6
- metadata.gz: c4588f0c10b1bb8bb3e8ac9afab01f1209588919b8939a3dbec5276eb5b8383c9f55f52e68e5f111a21c77d72cc57fd9acc4755797383a6c72bc4ed86e04c42a
7
- data.tar.gz: 22d3b703a28c5b561ac4f53d2e846333d2cda22b27e8e4931fe7ea64033d4436486e40b7f5d02838f06a4e76d88d7a7d44b98492b040794c57c23ec499baf935
6
+ metadata.gz: a09c19c44892cd6d2b8cc82b0fa82c8563fbed0c8734b8f12dfbb5906c223b664ab15e95cdeea8d2270004e06a182968d161bd644a044b157236e69141b8be80
7
+ data.tar.gz: a6ff074ebe7abd1a2029ffd6a3f04571ee75beb5709cef297a221bc37b3427fa84c5d53de767ccecf2f248e70a0cdf75fb8e363eb776ddec0b0aa9f1d2018c93
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ == 1.3.6
2
+
3
+ * (troessner) Add `Prima Donna Method` smell
4
+
1
5
  == 1.3.5
2
6
 
3
7
  * (troessner) Allow sorting by issue count
@@ -46,6 +46,9 @@ NestedIterators:
46
46
  NilCheck:
47
47
  enabled: true
48
48
  exclude: []
49
+ PrimaDonnaMethod:
50
+ enabled: true
51
+ exclude: []
49
52
  RepeatedConditional:
50
53
  enabled: true
51
54
  exclude: []
@@ -22,6 +22,10 @@ module Reek
22
22
  @exp.name
23
23
  end
24
24
 
25
+ def node_instance_methods
26
+ local_nodes(:defn)
27
+ end
28
+
25
29
  def local_nodes(type, &blk)
26
30
  each_node(type, [:class, :module], &blk)
27
31
  end
@@ -19,6 +19,7 @@ module Reek
19
19
  Smells::LongYieldList,
20
20
  Smells::NestedIterators,
21
21
  Smells::NilCheck,
22
+ Smells::PrimaDonnaMethod,
22
23
  Smells::RepeatedConditional,
23
24
  Smells::TooManyInstanceVariables,
24
25
  Smells::TooManyMethods,
@@ -10,6 +10,7 @@ require 'reek/smells/long_parameter_list'
10
10
  require 'reek/smells/long_yield_list'
11
11
  require 'reek/smells/nested_iterators'
12
12
  require 'reek/smells/nil_check'
13
+ require 'reek/smells/prima_donna_method'
13
14
  require 'reek/smells/repeated_conditional'
14
15
  require 'reek/smells/too_many_instance_variables'
15
16
  require 'reek/smells/too_many_methods'
@@ -0,0 +1,41 @@
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
+
4
+ module Reek
5
+ module Smells
6
+ # Excerpt from:
7
+ # http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist
8
+ # since this sums it up really well:
9
+ # ------------------------------
10
+ # The ! in method names that end with ! means, “This method is dangerous”
11
+ # or, more precisely, this method is the “dangerous” version of an
12
+ # equivalent method, with the same name minus the !. “Danger” is relative;
13
+ # the ! doesn’t mean anything at all unless the method name it’s in
14
+ # corresponds to a similar but bang-less method name. Don’t add ! to your
15
+ # destructive (receiver-changing) methods’ names, unless you consider the
16
+ # changing to be “dangerous” and you have a “non-dangerous” equivalent
17
+ # method without the !. If some arbitrary subset of destructive methods end
18
+ # with !, then the whole point of ! gets distorted and diluted, and ! ceases
19
+ # to convey any information whatsoever
20
+ # ------------------------------
21
+ # Such a method is called PrimaDonnaMethod and is reported as a smell.
22
+ class PrimaDonnaMethod < SmellDetector
23
+ SMELL_CLASS = smell_class_name
24
+ SMELL_SUBCLASS = smell_class_name
25
+
26
+ def self.contexts
27
+ [:class]
28
+ end
29
+
30
+ def examine_context(ctx)
31
+ ctx.node_instance_methods.map do |method_sexp|
32
+ if method_sexp.ends_with_bang?
33
+ SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
34
+ %Q!has prima donna method `#{method_sexp.name}`!,
35
+ @source, SMELL_SUBCLASS) unless ctx.node_instance_methods.detect {|sexp_item| sexp_item.name.to_s == method_sexp.name_without_bang }
36
+ end
37
+ end.compact
38
+ end
39
+ end
40
+ end
41
+ end
@@ -36,6 +36,10 @@ module Reek
36
36
  EXCLUDE_KEY => DEFAULT_EXCLUDE_SET.dup
37
37
  }
38
38
  end
39
+
40
+ def smell_class_name
41
+ name.split(/::/)[-1]
42
+ end
39
43
  end
40
44
 
41
45
  attr_reader :smells_found # SMELL: only published for tests
@@ -46,6 +46,14 @@ module Reek
46
46
  def parameter_names
47
47
  @param_names ||= argslist[1..-1].map { |param| Sexp === param ? param[1] : param }
48
48
  end
49
+
50
+ def name_without_bang
51
+ name.to_s.chop
52
+ end
53
+
54
+ def ends_with_bang?
55
+ name[-1] == '!'
56
+ end
49
57
  end
50
58
 
51
59
  module DefnNode
@@ -1,3 +1,3 @@
1
1
  module Reek
2
- VERSION = '1.3.5'
2
+ VERSION = '1.3.6'
3
3
  end
@@ -122,7 +122,7 @@ EOS
122
122
 
123
123
  it 'counts self references correctly' do
124
124
  src = <<EOS
125
- def adopt!(other)
125
+ def adopt(other)
126
126
  other.keys.each do |key|
127
127
  self[key] += 3
128
128
  self[key] = o4
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ require 'reek/smells/smell_detector_shared'
4
+
5
+ include Reek
6
+ include Reek::Smells
7
+
8
+ describe PrimaDonnaMethod do
9
+ it 'should report nothing when method and bang counterpart exist' do
10
+ 'class C; def m; end; def m!; end; end'.should_not smell_of(PrimaDonnaMethod)
11
+ end
12
+
13
+ it 'should report PrimaDonnaMethod when only bang method exists' do
14
+ 'class C; def m!; end; end'.should smell_of(PrimaDonnaMethod)
15
+ end
16
+
17
+ describe 'the right smell' do
18
+ let(:detector) { PrimaDonnaMethod.new('dummy_source') }
19
+ let(:src) { 'class C; def m!; end; end' }
20
+ let(:ctx) { CodeContext.new(nil, src.to_reek_source.syntax_tree) }
21
+
22
+ it 'should be reported' do
23
+ smells = detector.examine_context(ctx)
24
+ warning = smells[0]
25
+
26
+ warning.smell['class'].should == 'PrimaDonnaMethod'
27
+ warning.smell['subclass'].should == 'PrimaDonnaMethod'
28
+ warning.lines.should == [1]
29
+ end
30
+ end
31
+ end
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: 1.3.5
4
+ version: 1.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Rutherford
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-12-23 00:00:00.000000000 Z
13
+ date: 2013-12-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ruby_parser
@@ -187,6 +187,7 @@ files:
187
187
  - lib/reek/version.rb
188
188
  - lib/reek/smells/boolean_parameter.rb
189
189
  - lib/reek/smells/uncommunicative_parameter_name.rb
190
+ - lib/reek/smells/prima_donna_method.rb
190
191
  - lib/reek/smells/unused_parameters.rb
191
192
  - lib/reek/smells/long_yield_list.rb
192
193
  - lib/reek/smells/attribute.rb
@@ -245,6 +246,7 @@ files:
245
246
  - spec/reek/cli/yaml_command_spec.rb
246
247
  - spec/reek/cli/report_spec.rb
247
248
  - spec/reek/cli/version_command_spec.rb
249
+ - spec/reek/smells/prima_donna_method_spec.rb
248
250
  - spec/reek/smells/boolean_parameter_spec.rb
249
251
  - spec/reek/smells/uncommunicative_method_name_spec.rb
250
252
  - spec/reek/smells/uncommunicative_module_name_spec.rb