pippi 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0c609506ea54efa1618cc91626c3a1b0d13619ce
4
- data.tar.gz: 815ea5e17c5562c9eee9c8cffe7025c759036995
3
+ metadata.gz: 5ad992cb9bc5aa2b1e2ea7ee7acbe531cbb2432e
4
+ data.tar.gz: 564a5feffa9d49e8eb28d878f4635c93ba19921e
5
5
  SHA512:
6
- metadata.gz: db93b8205fcfd68ebce496b74701165719364b90d5ffe9f06609e7a1bec19a4fdc5a14766d01dbf8a0138cd42d6a9ec9b2cd69377f15ca5e3cb4c6ea0af7f2fc
7
- data.tar.gz: 2cb1d62ca2e910bb583b0cffa1bf67531b4b5bf6393133b93776b3e72787293fd3793b28adff09aff965e4464523c94365c61cb513c70ad0021124e6323ce6c6
6
+ metadata.gz: 9e1046f43ec28739b33a224136a3c852ea9a0c91579f5c22bff9f102e0fff483bb0ce9c97a9b93d2cb34d4a1c6fca390bfff9de1ec2020488d96d7ff6d88faec
7
+ data.tar.gz: 822431d1b25e296483f2031a8ec581788615e6c1d89b02b9fee1fd4474172c72e8b753cbcaaae81f1e51564cc881a6ae38a7dd92ff3dfa5ec9dad96bb15f5879
@@ -1,3 +1,7 @@
1
+ ## 0.0.10 (2014-12-09)
2
+
3
+ * [NEW] Added SelectFollowedByNone
4
+
1
5
  ## 0.0.9 (2014-12-04)
2
6
 
3
7
  * [FIXED] False positives reduced
data/README.md CHANGED
@@ -189,6 +189,22 @@ Instead, consider doing this:
189
189
  [1,2,3].detect {|x| x > 1 }
190
190
  ```
191
191
 
192
+ #### SelectFollowedByNone
193
+
194
+ Don't use select followed by none?; use none? with a block instead
195
+
196
+ For example, rather than doing this:
197
+
198
+ ```ruby
199
+ [1,2,3].select {|x| x > 1 }.none?
200
+ ```
201
+
202
+ Instead, consider doing this:
203
+
204
+ ```ruby
205
+ [1,2,3].none? {|x| x > 1 }
206
+ ```
207
+
192
208
  #### SelectFollowedBySelect
193
209
 
194
210
  Don't use consecutive select blocks; use a single select instead
@@ -257,8 +273,6 @@ Instead, consider doing this:
257
273
  ## Ideas for other problems to detect:
258
274
 
259
275
  ```ruby
260
- # Don't use select followed by compact, use select with the nil inside the block
261
-
262
276
  # unnecessary assignment since String#strip! mutates receiver
263
277
  # wrong
264
278
  x = x.strip!
@@ -320,7 +334,8 @@ end
320
334
 
321
335
  * Clean up this initial hacked out metaprogramming
322
336
  * Do more checks
323
- * Make writing rules nicer, without some much dorking around with methods. "select followed by first" could be specified with something like "Array#select => #first" and the rest left up to the framework.
337
+ * Finish refactoring duplicated code into MethodSequenceChecker
338
+ * Use MethodSequenceFinder to do something with String
324
339
 
325
340
  ## Developing
326
341
 
@@ -64,6 +64,22 @@ Instead, consider doing this:
64
64
  [1,2,3].detect {|x| x > 1 }
65
65
  ```
66
66
 
67
+ #### SelectFollowedByNone
68
+
69
+ Don't use select followed by none?; use none? with a block instead
70
+
71
+ For example, rather than doing this:
72
+
73
+ ```ruby
74
+ [1,2,3].select {|x| x > 1 }.none?
75
+ ```
76
+
77
+ Instead, consider doing this:
78
+
79
+ ```ruby
80
+ [1,2,3].none? {|x| x > 1 }
81
+ ```
82
+
67
83
  #### SelectFollowedBySelect
68
84
 
69
85
  Don't use consecutive select blocks; use a single select instead
@@ -14,6 +14,9 @@ require 'pippi/checks/select_followed_by_first'
14
14
  require 'pippi/checks/select_followed_by_size'
15
15
  require 'pippi/checks/select_followed_by_empty'
16
16
  require 'pippi/checks/select_followed_by_any'
17
+ require 'pippi/checks/select_followed_by_none'
17
18
  require 'pippi/checks/select_followed_by_select'
19
+ require 'pippi/checks/method_sequence_finder'
20
+ require 'pippi/checks/method_sequence_checker'
18
21
  require 'pippi/checks/assert_with_nil'
19
22
  require 'pippi/checks/debug_check'
@@ -5,11 +5,16 @@ module Pippi
5
5
  def initialize(opts = {})
6
6
  checkset = opts.fetch(:checkset, 'basic')
7
7
  @ctx = Pippi::Context.new
8
- Pippi::CheckLoader.new(@ctx, checkset).checks.each(&:decorate)
8
+
9
+ @ctx.checks = Pippi::CheckLoader.new(@ctx, checkset).checks
10
+ @ctx.checks.each(&:decorate)
9
11
  at_exit { dump }
10
12
  end
11
13
 
12
14
  def dump
15
+ if @ctx.checks.one? && @ctx.checks.first.kind_of?(Pippi::Checks::MethodSequenceFinder)
16
+ @ctx.checks.first.dump
17
+ end
13
18
  File.open('log/pippi.log', 'w') do |outfile|
14
19
  @ctx.report.problems.each do |problem|
15
20
  outfile.syswrite("#{problem.to_text}\n")
@@ -23,12 +23,16 @@ module Pippi
23
23
  "SelectFollowedByFirst",
24
24
  "SelectFollowedBySize",
25
25
  "SelectFollowedByAny",
26
+ "SelectFollowedByNone",
26
27
  "SelectFollowedByEmpty",
27
28
  "ReverseFollowedByEach",
28
29
  "SelectFollowedBySelect"
29
30
  ],
30
31
  "training" => [
31
32
  ],
33
+ "research" => [
34
+ "MethodSequenceFinder",
35
+ ],
32
36
  "buggy" => [
33
37
  "AssertWithNil",
34
38
  "MapFollowedByFlatten",
@@ -1,4 +1,6 @@
1
1
  module Pippi::Checks
2
+
3
+ # TODO make this use MethodSequenceChecker
2
4
  class MapFollowedByFlatten < Check
3
5
  module MyFlatten
4
6
  def flatten(depth = nil)
@@ -0,0 +1,80 @@
1
+ class MethodSequenceChecker
2
+
3
+ ARITY_TYPE_BLOCK_ARG = 1
4
+ ARITY_TYPE_NONE = 2
5
+
6
+ attr_reader :check, :clazz_to_decorate, :method1, :method2, :first_method_arity_type, :second_method_arity_type, :should_check_subsequent_calls
7
+
8
+ def initialize(check, clazz_to_decorate, method1, method2, first_method_arity_type, second_method_arity_type, should_check_subsequent_calls)
9
+ @check = check
10
+ @clazz_to_decorate = clazz_to_decorate
11
+ @method1 = method1
12
+ @method2 = method2
13
+ @first_method_arity_type = first_method_arity_type
14
+ @second_method_arity_type = second_method_arity_type
15
+ @should_check_subsequent_calls = should_check_subsequent_calls
16
+ end
17
+
18
+ def decorate
19
+ clazz_to_decorate.class_exec(check, self) do |my_check, method_sequence_check_instance|
20
+ name = "@_pippi_check_#{my_check.class.name.split('::').last.downcase}"
21
+ self.instance_variable_set(name, my_check)
22
+ self.class.send(:define_method, name[1..-1]) do
23
+ instance_variable_get(name)
24
+ end
25
+
26
+ # e.g., "size" in "select followed by size"
27
+ second_method_decorator = Module.new do
28
+ define_method(method_sequence_check_instance.method2) do |*args, &blk|
29
+ self.class.instance_variable_get(name).add_problem
30
+ if method_sequence_check_instance.should_check_subsequent_calls && method_sequence_check_instance.clazz_to_decorate == Array
31
+ problem_location = caller_locations.find { |c| c.to_s !~ /byebug|lib\/pippi\/checks/ }
32
+ self.class.instance_variable_get(name).method_names_that_indicate_this_is_being_used_as_a_collection.each do |this_means_its_ok_sym|
33
+ define_singleton_method(this_means_its_ok_sym, self.class.instance_variable_get(name).clear_fault_proc(self.class.instance_variable_get(name), problem_location))
34
+ end
35
+ end
36
+ if method_sequence_check_instance.second_method_arity_type == ARITY_TYPE_BLOCK_ARG
37
+ super(&blk)
38
+ elsif method_sequence_check_instance.second_method_arity_type == ARITY_TYPE_NONE
39
+ super()
40
+ end
41
+ end
42
+ end
43
+
44
+ # e.g., "select" in "select followed ARITY_TYPE_NONEze"
45
+ first_method_decorator = Module.new do
46
+ define_method(method_sequence_check_instance.method1) do |*args, &blk|
47
+ result = if method_sequence_check_instance.first_method_arity_type == ARITY_TYPE_BLOCK_ARG
48
+ super(&blk)
49
+ elsif method_sequence_check_instance.first_method_arity_type == ARITY_TYPE_NONE
50
+ super()
51
+ end
52
+ if self.class.instance_variable_get(name)
53
+ result.extend second_method_decorator
54
+ self.class.instance_variable_get(name).array_mutator_methods.each do |this_means_its_ok_sym|
55
+ result.define_singleton_method(this_means_its_ok_sym, self.class.instance_variable_get(name).its_ok_watcher_proc(second_method_decorator, method_sequence_check_instance.method2))
56
+ end
57
+ end
58
+ result
59
+ end
60
+ end
61
+ prepend first_method_decorator
62
+ end
63
+ end
64
+
65
+ def array_mutator_methods
66
+ [:collect!, :compact!, :flatten!, :map!, :reject!, :reverse!, :rotate!, :select!, :shuffle!, :slice!, :sort!, :sort_by!, :uniq!]
67
+ end
68
+
69
+ def its_ok_watcher_proc(clazz, method_name)
70
+ proc do |*args, &blk|
71
+ begin
72
+ singleton_class.ancestors.find { |x| x == clazz }.instance_eval { remove_method method_name }
73
+ rescue NameError
74
+ return super(*args, &blk)
75
+ else
76
+ return super(*args, &blk)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,84 @@
1
+ module Pippi::Checks
2
+
3
+ module MyModule
4
+ def split(&blk)
5
+ result = super
6
+ if self.class._pippi_method_call_sequences
7
+ array_methods_to_track.each do |track_this|
8
+ result.define_singleton_method(track_this, track_it_proc(track_this))
9
+ end
10
+ end
11
+ result
12
+ end
13
+
14
+ def track_it_proc(method_name)
15
+ location = caller_locations.find { |c| c.to_s !~ /byebug|lib\/pippi\/checks/ }
16
+ proc do |*args, &blk|
17
+ begin
18
+ self.class._pippi_method_call_sequences.found_sequence(method_name, location)
19
+ rescue NameError
20
+ return super(*args, &blk)
21
+ else
22
+ return super(*args, &blk)
23
+ end
24
+ end
25
+ end
26
+
27
+ def string_methods_to_track
28
+ [:ascii_only?, :b, :between?, :bytes, :bytesize, :byteslice, :capitalize, :capitalize!, :casecmp, :center, :chars, :chomp, :chomp!, :chop, :chop!, :chr, :clear, :codepoints, :concat, :count, :crypt, :delete, :delete!, :downcase, :downcase!, :dump, :each_byte, :each_char, :each_codepoint, :each_line, :empty?, :encode, :encode!, :encoding, :end_with?, :force_encoding, :getbyte, :gsub, :gsub!, :hex, :index, :insert, :intern, :length, :lines, :ljust, :lstrip, :lstrip!, :match, :next, :next!, :oct, :ord, :partition, :replace, :reverse, :reverse!, :rindex, :rjust, :rpartition, :rstrip, :rstrip!, :scan, :scrub, :scrub!, :setbyte, :size, :slice, :slice!, :split, :squeeze, :squeeze!, :start_with?, :strip, :strip!, :sub, :sub!, :succ, :succ!, :sum, :swapcase, :swapcase!, :to_c, :to_f, :to_i, :to_r, :to_str, :to_sym, :tr, :tr!, :tr_s, :tr_s!, :unpack, :upcase, :upcase!, :upto, :valid_encoding?]
29
+ end
30
+
31
+ def array_methods_to_track
32
+ [:all?, :any?, :assoc, :at, :bsearch, :chunk, :clear, :collect, :collect!, :collect_concat, :combination, :compact, :compact!, :concat, :count, :cycle, :delete, :delete_at, :delete_if, :detect, :drop, :drop_while, :each, :each_cons, :each_entry, :each_index, :each_slice, :each_with_index, :each_with_object, :empty?, :entries, :fetch, :fill, :find, :find_all, :find_index, :first, :flat_map, :flatten, :flatten!, :grep, :group_by, :histogram, :index, :inject, :insert, :join, :keep_if, :last, :lazy, :length, :map, :map!, :max, :max_by, :member?, :min, :min_by, :minmax, :minmax_by, :none?, :one?, :pack, :partition, :permutation, :pop, :product, :push, :rassoc, :reduce, :reject, :reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!, :reverse_each, :rindex, :rotate, :rotate!, :sample, :select, :select!, :shift, :shuffle, :shuffle!, :size, :slice, :slice!, :slice_before, :sort, :sort!, :sort_by, :sort_by!, :take, :take_while, :to_a, :to_ary, :to_h, :transpose, :uniq, :uniq!, :unshift, :values_at, :zip]
33
+ end
34
+ end
35
+
36
+ class MethodSequenceFinder < Check
37
+
38
+ class Record
39
+ attr_reader :path, :lineno, :meth1, :meth2
40
+ def initialize(path, lineno, meth1, meth2)
41
+ @path = path
42
+ @lineno = lineno
43
+ @meth1 = meth1
44
+ @meth2 = meth2
45
+ end
46
+ def eql?(other)
47
+ path == other.path && lineno == other.lineno && meth1 == other.meth1 && meth2 == other.meth2
48
+ end
49
+ def hash
50
+ require 'zlib'
51
+ Zlib.crc32("#{path}:#{lineno}:#{meth1}:#{meth2}")
52
+ end
53
+ end
54
+
55
+ attr_reader :sequences, :clazz_to_decorate
56
+
57
+ def initialize(ctx)
58
+ super
59
+ @clazz_to_decorate = String
60
+ @sequences = Set.new
61
+ end
62
+
63
+ def dump
64
+ @sequences.map {|r| "#{r.meth1}:#{r.meth2}" }.inject({}) {|m,i| m[i] ||= 0 ; m[i] += 1 ; m }.to_a.sort_by {|x| x[1] }.reverse.each do |r|
65
+ puts "#{r[0].split(':')[0]} followed by #{r[0].split(':')[1]} occurred #{r[1]} times\n"
66
+ end
67
+ end
68
+
69
+ def found_sequence(method_name, location)
70
+ @sequences << Record.new(location.path, location.lineno, "map", method_name)
71
+ end
72
+
73
+ def decorate
74
+ clazz_to_decorate.class_exec(self) do |my_check|
75
+ @_pippi_method_call_sequences = my_check
76
+ class << self
77
+ attr_reader :_pippi_method_call_sequences
78
+ end
79
+ prepend MyModule
80
+ end
81
+ end
82
+
83
+ end
84
+ end
@@ -1,4 +1,6 @@
1
1
  module Pippi::Checks
2
+
3
+ # TODO make this use MethodSequenceChecker
2
4
  class ReverseFollowedByEach < Check
3
5
  module MyEach
4
6
  def each
@@ -2,41 +2,13 @@ module Pippi::Checks
2
2
 
3
3
  class SelectFollowedByAny < Check
4
4
 
5
- module MyAny
6
- def any?(&blk)
7
- self.class._pippi_check_select_followed_by_any.add_problem
8
- problem_location = caller_locations.find { |c| c.to_s !~ /byebug|lib\/pippi\/checks/ }
9
- self.class._pippi_check_select_followed_by_any.method_names_that_indicate_this_is_being_used_as_a_collection.each do |this_means_its_ok_sym|
10
- define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_any.clear_fault_proc(self.class._pippi_check_select_followed_by_any, problem_location))
11
- end
12
- super
13
- end
14
- end
15
-
16
- module MySelect
17
- def select(&blk)
18
- result = super
19
- if self.class._pippi_check_select_followed_by_any.nil?
20
- # Ignore Array subclasses since select or any may have difference meanings
21
- # elsif defined?(ActiveRecord::Relation) && self.class.kind_of?(ActiveRecord::Relation) # maybe also this
22
- else
23
- result.extend MyAny
24
- self.class._pippi_check_select_followed_by_any.array_mutator_methods.each do |this_means_its_ok_sym|
25
- result.define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_any.its_ok_watcher_proc(MyAny, :any?))
26
- end
27
- end
28
- result
29
- end
5
+ def decorate
6
+ @mycheck.decorate
30
7
  end
31
8
 
32
- def decorate
33
- Array.class_exec(self) do |my_check|
34
- @_pippi_check_select_followed_by_any = my_check
35
- def self._pippi_check_select_followed_by_any
36
- @_pippi_check_select_followed_by_any
37
- end
38
- prepend MySelect
39
- end
9
+ def initialize(ctx)
10
+ super
11
+ @mycheck = MethodSequenceChecker.new(self, Array, "select", "any?", MethodSequenceChecker::ARITY_TYPE_BLOCK_ARG, MethodSequenceChecker::ARITY_TYPE_NONE, true)
40
12
  end
41
13
 
42
14
  class Documentation
@@ -2,41 +2,13 @@ module Pippi::Checks
2
2
 
3
3
  class SelectFollowedByEmpty < Check
4
4
 
5
- module MyEmpty
6
- def empty?(&blk)
7
- self.class._pippi_check_select_followed_by_empty.add_problem
8
- problem_location = caller_locations.find { |c| c.to_s !~ /byebug|lib\/pippi\/checks/ }
9
- self.class._pippi_check_select_followed_by_empty.method_names_that_indicate_this_is_being_used_as_a_collection.each do |this_means_its_ok_sym|
10
- define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_empty.clear_fault_proc(self.class._pippi_check_select_followed_by_empty, problem_location))
11
- end
12
- super
13
- end
14
- end
15
-
16
- module MySelect
17
- def select(&blk)
18
- result = super
19
- if self.class._pippi_check_select_followed_by_empty.nil?
20
- # Ignore Array subclasses since select or empty may have difference meanings
21
- # elsif defined?(ActiveRecord::Relation) && self.class.kind_of?(ActiveRecord::Relation) # maybe also this
22
- else
23
- result.extend MyEmpty
24
- self.class._pippi_check_select_followed_by_empty.array_mutator_methods.each do |this_means_its_ok_sym|
25
- result.define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_empty.its_ok_watcher_proc(MyEmpty, :empty?))
26
- end
27
- end
28
- result
29
- end
5
+ def decorate
6
+ @mycheck.decorate
30
7
  end
31
8
 
32
- def decorate
33
- Array.class_exec(self) do |my_check|
34
- @_pippi_check_select_followed_by_empty = my_check
35
- def self._pippi_check_select_followed_by_empty
36
- @_pippi_check_select_followed_by_empty
37
- end
38
- prepend MySelect
39
- end
9
+ def initialize(ctx)
10
+ super
11
+ @mycheck = MethodSequenceChecker.new(self, Array, "select", "empty?", MethodSequenceChecker::ARITY_TYPE_BLOCK_ARG, MethodSequenceChecker::ARITY_TYPE_NONE, true)
40
12
  end
41
13
 
42
14
  class Documentation
@@ -1,5 +1,7 @@
1
1
  module Pippi::Checks
2
2
  class SelectFollowedByFirst < Check
3
+
4
+ # TODO make this use MethodSequenceChecker
3
5
  module MyFirst
4
6
  def first(elements = nil)
5
7
  unless elements
@@ -0,0 +1,28 @@
1
+ module Pippi::Checks
2
+
3
+ class SelectFollowedByNone < Check
4
+
5
+ def decorate
6
+ @mycheck.decorate
7
+ end
8
+
9
+ def initialize(ctx)
10
+ super
11
+ @mycheck = MethodSequenceChecker.new(self, Array, "select", "none?", MethodSequenceChecker::ARITY_TYPE_BLOCK_ARG, MethodSequenceChecker::ARITY_TYPE_NONE, true)
12
+ end
13
+
14
+ class Documentation
15
+ def description
16
+ "Don't use select followed by none?; use none? with a block instead"
17
+ end
18
+ def sample
19
+ "[1,2,3].select {|x| x > 1 }.none?"
20
+ end
21
+ def instead_use
22
+ "[1,2,3].none? {|x| x > 1 }"
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -2,34 +2,13 @@ module Pippi::Checks
2
2
 
3
3
  class SelectFollowedBySelect < Check
4
4
 
5
- module MySecondSelect
6
- def select(&blk)
7
- self.class._pippi_check_select_followed_by_select.add_problem
8
- super
9
- end
10
- end
11
-
12
- module MyFirstSelect
13
- def select(&blk)
14
- result = super
15
- if !self.class._pippi_check_select_followed_by_select.nil?
16
- result.extend MySecondSelect
17
- self.class._pippi_check_select_followed_by_select.array_mutator_methods.each do |this_means_its_ok_sym|
18
- result.define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_select.its_ok_watcher_proc(MySecondSelect, :select))
19
- end
20
- end
21
- result
22
- end
5
+ def decorate
6
+ @mycheck.decorate
23
7
  end
24
8
 
25
- def decorate
26
- Array.class_exec(self) do |my_check|
27
- @_pippi_check_select_followed_by_select = my_check
28
- def self._pippi_check_select_followed_by_select
29
- @_pippi_check_select_followed_by_select
30
- end
31
- prepend MyFirstSelect
32
- end
9
+ def initialize(ctx)
10
+ super
11
+ @mycheck = MethodSequenceChecker.new(self, Array, "select", "select", MethodSequenceChecker::ARITY_TYPE_BLOCK_ARG, MethodSequenceChecker::ARITY_TYPE_BLOCK_ARG, false)
33
12
  end
34
13
 
35
14
  class Documentation
@@ -1,39 +1,13 @@
1
1
  module Pippi::Checks
2
2
  class SelectFollowedBySize < Check
3
- module MySize
4
- def size
5
- self.class._pippi_check_select_followed_by_size.add_problem
6
- problem_location = caller_locations.find { |c| c.to_s !~ /byebug|lib\/pippi\/checks/ }
7
- self.class._pippi_check_select_followed_by_size.method_names_that_indicate_this_is_being_used_as_a_collection.each do |this_means_its_ok_sym|
8
- define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_size.clear_fault_proc(self.class._pippi_check_select_followed_by_size, problem_location))
9
- end
10
- super()
11
- end
12
- end
13
3
 
14
- module MySelect
15
- def select(&blk)
16
- result = super
17
- if self.class._pippi_check_select_followed_by_size.nil?
18
- # Ignore Array subclasses since select or size may have difference meanings
19
- else
20
- result.extend MySize
21
- self.class._pippi_check_select_followed_by_size.array_mutator_methods.each do |this_means_its_ok_sym|
22
- result.define_singleton_method(this_means_its_ok_sym, self.class._pippi_check_select_followed_by_size.its_ok_watcher_proc(MySize, :size))
23
- end
24
- end
25
- result
26
- end
4
+ def decorate
5
+ @mycheck.decorate
27
6
  end
28
7
 
29
- def decorate
30
- Array.class_exec(self) do |my_check|
31
- @_pippi_check_select_followed_by_size = my_check
32
- class << self
33
- attr_reader :_pippi_check_select_followed_by_size
34
- end
35
- prepend MySelect
36
- end
8
+ def initialize(ctx)
9
+ super
10
+ @mycheck = MethodSequenceChecker.new(self, Array, "select", "size", MethodSequenceChecker::ARITY_TYPE_BLOCK_ARG, MethodSequenceChecker::ARITY_TYPE_NONE, true)
37
11
  end
38
12
 
39
13
  class Documentation
@@ -1,5 +1,8 @@
1
1
  module Pippi
2
2
  class Context
3
+
4
+ attr_accessor :checks
5
+
3
6
  class DebugLogger
4
7
  def warn(str)
5
8
  File.open('pippi_debug.log', 'a') do |f|
@@ -4,7 +4,7 @@ module Pippi
4
4
  class Documentation
5
5
  def generate
6
6
  str = ''
7
- Pippi::CheckSetMapper.new("").predefined_sets.sort.select {|k,v| v.any? }.each do |checkset_name, checks|
7
+ Pippi::CheckSetMapper.new("").predefined_sets.sort.select {|k,v| k != "research" && v.any? }.each do |checkset_name, checks|
8
8
  str << "### #{checkset_name}\n"
9
9
  checks.sort.each do |check|
10
10
  obj = Object.const_get("Pippi::Checks::#{check}::Documentation").new
@@ -1,3 +1,3 @@
1
1
  module Pippi
2
- VERSION = '0.0.9'
2
+ VERSION = '0.0.10'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pippi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Copeland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-05 00:00:00.000000000 Z
11
+ date: 2014-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -73,10 +73,13 @@ files:
73
73
  - lib/pippi/checks/check.rb
74
74
  - lib/pippi/checks/debug_check.rb
75
75
  - lib/pippi/checks/map_followed_by_flatten.rb
76
+ - lib/pippi/checks/method_sequence_checker.rb
77
+ - lib/pippi/checks/method_sequence_finder.rb
76
78
  - lib/pippi/checks/reverse_followed_by_each.rb
77
79
  - lib/pippi/checks/select_followed_by_any.rb
78
80
  - lib/pippi/checks/select_followed_by_empty.rb
79
81
  - lib/pippi/checks/select_followed_by_first.rb
82
+ - lib/pippi/checks/select_followed_by_none.rb
80
83
  - lib/pippi/checks/select_followed_by_select.rb
81
84
  - lib/pippi/checks/select_followed_by_size.rb
82
85
  - lib/pippi/context.rb