pippi 0.0.9 → 0.0.10

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: 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