peeky 0.0.42 → 0.0.48

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
  SHA256:
3
- metadata.gz: 920d6f10ed0e11acad5844cc60e290ba9e7ee85e27e801cf766e6934e6e3ea06
4
- data.tar.gz: 4637e61e368dba0a5c4a9c3e8b0e8ff058b11c939ea848040eeff4a71a15e627
3
+ metadata.gz: b101eb2cf5f68f0a26a46579ddc1b87df3f8b2edbfefa9aa8301a8efe1b6f44a
4
+ data.tar.gz: 56e16cec9351212f107137cb1efda57c0221a8ffac84945b36a51231f66536c4
5
5
  SHA512:
6
- metadata.gz: 56c35b423fb6b786a187548d9b9fe9a1d76f47da18dd6fb53eea1143593cbcfb6ff19de8f2ac5237193b6df7250726ef73d9e3c287655ded452331f99bca05f0
7
- data.tar.gz: cd58b3be796b1e185a697ac3f6dca2836154750bf856b4455e4dbd6c7224d6b629e3bd3184dd67ebd0195b0293affbb3feadfc62f9032fb07948f0b1bfafa2c0
6
+ metadata.gz: 8bef9b277830666604a788bdc0f1dc242b5d58c15d1c44d83a58ad559fc883d6888b1fbfde996514af27b4e90729d65a69c5b49ce81df7c79685ce89f7d953b1
7
+ data.tar.gz: 8c650d21456723d845c994d117a30ca9a6dcb5dbc26bb35a12b50bf33805f4ba863f8de665b8265a0d58cf5ee1eb17f2aa035b00c3ba1044624661becc6e24c9
data/Guardfile CHANGED
@@ -23,7 +23,7 @@ group :green_pass_then_cop, halt_on_fail: true do
23
23
  watch(%r{^lib/peeky/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
24
24
  end
25
25
 
26
- guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
26
+ guard :rubocop, all_on_start: false, cli: ['--format', 'clang', '-a'] do
27
27
  watch(%r{.+\.rb$})
28
28
  watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
29
29
  end
@@ -17,6 +17,20 @@ module Peeky
17
17
  @instance = instance
18
18
  end
19
19
 
20
+ def to_h
21
+ {
22
+ class_name: class_name,
23
+ module_name: module_name,
24
+ class_full_name: class_full_name,
25
+ attr_accessor: accessors.map(&:name),
26
+ attr_reader: readers.map(&:name),
27
+ attr_writer: writers.map(&:name),
28
+ klass: methods_to_h(class_methods),
29
+ instance_public: methods_to_h(public_methods),
30
+ instance_private: methods_to_h(private_methods)
31
+ }
32
+ end
33
+
20
34
  # rubocop:disable Metrics/AbcSize
21
35
  def to_s
22
36
  result = []
@@ -33,13 +47,16 @@ module Peeky
33
47
  result.push kv('# of methods', all_methods.length)
34
48
  result.push kv('# of methods - public', public_methods.length)
35
49
  result.push kv('# of methods - private', private_methods.length)
50
+ result.push kv('# of class methods', class_methods.length)
51
+
36
52
  else
37
- result.push kv('# of accessors', '')
38
- result.push kv('# of readers', '')
39
- result.push kv('# of writers', '')
40
- result.push kv('# of methods', '')
41
- result.push kv('# of methods - public', '')
42
- result.push kv('# of methods - private', '')
53
+ result.push 'Not Loaded'
54
+ # result.push kv('# of accessors', '')
55
+ # result.push kv('# of readers', '')
56
+ # result.push kv('# of writers', '')
57
+ # result.push kv('# of methods', '')
58
+ # result.push kv('# of methods - public', '')
59
+ # result.push kv('# of methods - private', '')
43
60
  end
44
61
  result.join("\n")
45
62
  end
@@ -53,8 +70,6 @@ module Peeky
53
70
  # At times during debug or other edge cases, it may be useful to
54
71
  # pre-load this information early.
55
72
  def load
56
- ruby_instance_methods
57
- # ruby_instance_method_names
58
73
  signatures
59
74
  end
60
75
 
@@ -71,7 +86,13 @@ module Peeky
71
86
 
72
87
  # Module name
73
88
  def module_name
74
- @module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
89
+ return @module_name if defined? @module_name
90
+
91
+ @module_name = if class_full_name.include?('::')
92
+ class_full_name.to_s.gsub(/(.*)::.*/, '\1')
93
+ else
94
+ ''
95
+ end
75
96
  end
76
97
 
77
98
  # Get a list of :attr_accessor on the class
@@ -122,6 +143,12 @@ module Peeky
122
143
  @public_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :public }
123
144
  end
124
145
 
146
+ # Get a list of class methods
147
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
148
+ def class_methods
149
+ @class_methods ||= signatures.select { |signature| signature.implementation_type == :class_method }
150
+ end
151
+
125
152
  # Get a list methods ordered the way they are in the source code
126
153
  # @return [Array<MethodInfo>] list of MethodInfo
127
154
  def methods_source_order
@@ -180,9 +207,10 @@ module Peeky
180
207
  return @signatures if defined? @signatures
181
208
 
182
209
  @signatures = begin
183
- instance_methods = ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
184
- private_methods = ruby_private_methods.map { |im| MethodInfo.new(im, @instance, access_control: :private) }
185
- instance_methods + private_methods
210
+ instance_methods = ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
211
+ private_methods = ruby_private_methods.map { |im| MethodInfo.new(im, @instance, access_control: :private) }
212
+ class_methods = ruby_class_methods.map { |im| MethodInfo.new(im, @instance, implementation_type: :class_method) }
213
+ instance_methods + private_methods + class_methods
186
214
  end
187
215
  end
188
216
 
@@ -209,6 +237,10 @@ module Peeky
209
237
  "#{key.to_s.ljust(25)}: #{value}"
210
238
  end
211
239
 
240
+ def ruby_class_method_names
241
+ @ruby_class_method_names ||= instance.class.methods(false).sort # singleton_class.instance_methods(false).sort
242
+ end
243
+
212
244
  def ruby_instance_method_names
213
245
  @ruby_instance_method_names ||= instance.class.instance_methods(false).sort
214
246
  end
@@ -217,16 +249,40 @@ module Peeky
217
249
  @ruby_private_method_names ||= instance.private_methods(false).sort
218
250
  end
219
251
 
252
+ def ruby_class_methods
253
+ @ruby_class_methods ||= ruby_class_method_names.map { |method_name| instance.class.method(method_name) }
254
+ rescue StandardError => e
255
+ # puts 'ruby_class_methods'
256
+ puts e
257
+ end
258
+
220
259
  def ruby_private_methods
221
260
  @ruby_private_methods ||= ruby_private_method_names.map { |method_name| instance.method(method_name) }
222
261
  rescue StandardError => e
262
+ # puts 'ruby_private_methods'
223
263
  puts e
224
264
  end
225
265
 
226
266
  def ruby_instance_methods
227
267
  @ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
228
268
  rescue StandardError => e
269
+ # puts 'ruby_instance_methods'
229
270
  puts e
230
271
  end
272
+
273
+ def methods_to_h(methods)
274
+ methods.map do |m|
275
+ {
276
+ name: m.name,
277
+ paramaters: m.parameters.map do |p|
278
+ {
279
+ name: p.name,
280
+ type: p.type,
281
+ default_value: p.default_value
282
+ }
283
+ end
284
+ }
285
+ end
286
+ end
231
287
  end
232
288
  end
@@ -22,21 +22,21 @@ module Peeky
22
22
  #
23
23
 
24
24
  # Implementation type indicates the probable representation of this
25
- # method in ruby, was it `def method` or `attr_reader` / `attr_writer`
25
+ # method in ruby, was it
26
+ # instance method `def method`
27
+ # instance method reader `attr_reader`
28
+ # instance method writer `attr_writer`
29
+ # class method `def self.method`
26
30
  attr_reader :implementation_type
27
31
 
28
- def initialize(method, target_instance, access_control: :public)
32
+ def initialize(method, target_instance, implementation_type: :method, access_control: :public)
29
33
  @focal_method = method
30
34
  @target_instance = target_instance
31
35
  @access_control = access_control
36
+ @implementation_type = implementation_type
32
37
  @parameters = ParameterInfo.from_method(method)
33
- # stage 1
34
- # @implementation_type = :method
35
38
 
36
- # stage 2
37
39
  infer_implementation_type
38
-
39
- # stage 3
40
40
  infer_default_paramaters
41
41
  end
42
42
 
@@ -55,20 +55,13 @@ module Peeky
55
55
  end
56
56
  end
57
57
 
58
- # Infer implementation type [:method, :attr_reader or :attr_writer]
59
- # rubocop:disable Lint/DuplicateBranch
58
+ # Infer implementation type [:class_method, :method, :attr_reader or :attr_writer]
60
59
  def infer_implementation_type
61
- @implementation_type = if @target_instance.nil?
62
- :method
63
- elsif match(Peeky::Predicates::AttrReaderPredicate)
64
- :attr_reader
65
- elsif match(Peeky::Predicates::AttrWriterPredicate)
66
- :attr_writer
67
- else
68
- :method
69
- end
60
+ return unless @implementation_type == :method
61
+
62
+ @implementation_type = :attr_reader if match(Peeky::Predicates::AttrReaderPredicate)
63
+ @implementation_type = :attr_writer if match(Peeky::Predicates::AttrWriterPredicate)
70
64
  end
71
- # rubocop:enable Lint/DuplicateBranch
72
65
 
73
66
  # Get parameter by name
74
67
  #
@@ -95,13 +88,16 @@ module Peeky
95
88
  # The tests are now down to 5 seconds, but it highlights the cost of use
96
89
  # TracePoint.
97
90
  def infer_default_paramaters
98
- minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self).render
91
+ class_name = @implementation_type == :class_method ? @target_instance.class.name : nil
92
+ minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self, class_name: class_name).render
99
93
 
100
94
  return if minimalist_method.end_with?('=')
101
95
  return unless optional?
102
96
 
103
97
  tracer.enable do
104
- @target_instance.instance_eval(minimalist_method)
98
+ # TODO: minimalist method should be able to handle class methods
99
+ @target_instance.instance_eval(minimalist_method) if @implementation_type == :method
100
+ @target_instance.class.instance_eval(minimalist_method) if @implementation_type == :class_method
105
101
  rescue StandardError => e
106
102
  # just print the error for now, we are only attempting to capture the
107
103
  # first call, any errors inside the call cannot be dealt with and should
@@ -24,21 +24,9 @@ module Peeky
24
24
  output.push('')
25
25
  end
26
26
 
27
- methods = render_methods(@class_info.public_methods)
28
-
29
- if methods.length.positive?
30
- output.push("-- Public Methods #{'-' * 82}")
31
- output.push(*methods)
32
- output.push('')
33
- end
34
-
35
- methods = render_methods(@class_info.private_methods)
36
-
37
- if methods.length.positive?
38
- output.push("-- Private Methods #{'-' * 82}")
39
- output.push(*methods)
40
- output.push('')
41
- end
27
+ render_methods_with_heading(output, @class_info.public_methods, 'Public Methods')
28
+ render_methods_with_heading(output, @class_info.class_methods, 'Class Methods')
29
+ render_methods_with_heading(output, @class_info.private_methods, 'Private Methods')
42
30
 
43
31
  output.pop if output.last == ''
44
32
 
@@ -78,6 +66,16 @@ module Peeky
78
66
  @class_info.writers.map { |attr| kv('attr_writer', attr.name) }
79
67
  end
80
68
 
69
+ def render_methods_with_heading(output, method_list, heading)
70
+ methods = render_methods(method_list)
71
+
72
+ return unless methods.length.positive?
73
+
74
+ output.push("-- #{heading} #{'-' * 82}")
75
+ output.push(*methods)
76
+ output.push('')
77
+ end
78
+
81
79
  def render_methods(method_list)
82
80
  method_list.flat_map do |method|
83
81
  [
@@ -2,32 +2,44 @@
2
2
 
3
3
  module Peeky
4
4
  module Renderer
5
- # Render: Class Interface
5
+ # Render: Class Interface Example
6
6
  #
7
- # Example output:
8
- # class SampleClassClassInterfaceRender
9
- # attr_accessor :a
7
+ # class ComplexClass
8
+ # attr_accessor :a_read_write1
9
+ # attr_accessor :a_read_write2
10
+
11
+ # attr_reader :b_another_reader
12
+ # attr_reader :b_reader
13
+ # attr_reader :looks_like_an_attr_reader
14
+
15
+ # attr_writer :c_another_writer
16
+ # attr_writer :c_writer
17
+
18
+ # def alpha_sort1; end
19
+ # def alpha_sort2; end
20
+ # def destructive!; end
21
+ # def do_something_method; end
22
+ # def method_01(aaa); end
23
+ # def method_02(aaa, bbb = 1); end
24
+ # def method_03(aaa, bbb = 1, ccc = 2); end
25
+ # def method_04(*aaa); end
26
+ # def method_05(aaa, bbb = 1, *ccc); end
27
+ # def method_06(**aaa); end
28
+ # def method_07(aaa, *bbb, ccc: 'string1', **ddd); end
29
+ # def method_08(aaa, *bbb, **ccc, &ddd); end
30
+ # def method_09(aaa:); end
31
+ # def method_10(aaa:, bbb: 1); end
32
+ # def method_with_every_type_of_paramater(aaa, bbb = 1, *ccc, ddd:, eee: 1, **fff, &ggg);end
33
+ # def questionable?; end
10
34
  #
11
- # attr_reader :b
35
+ # class << self
36
+ # def klass_complex(aaa, bbb = nil, *ccc, ddd:, eee: , **fff, &ggg); end
37
+ # def klass_simple(first_param); end
38
+ # end
12
39
  #
13
- # attr_writer :c
40
+ # private
14
41
  #
15
- # def alpha_sort1; end
16
- # def alpha_sort2; end
17
- # def d; end
18
- # def e(aaa); end
19
- # def f(aaa, bbb = nil); end
20
- # def g(aaa, bbb = nil, ccc = nil); end
21
- # def h(*aaa); end
22
- # def i(aaa, bbb, *ccc); end
23
- # def j(**aaa); end
24
- # def k(aaa, *bbb, **ccc); end
25
- # def l(aaa, *bbb, **ccc, &ddd); end
26
- # def m(aaa:); end
27
- # def n(aaa:, bbb: nil); end
28
- # def p?; end
29
- # def q!; end
30
- # def z(aaa, bbb = nil, *ccc, ddd:, eee: nil, **fff, &ggg); end
42
+ # def keep_me_private; end
31
43
  # end
32
44
  class ClassInterfaceRender
33
45
  # ClassInfo with information about the class instance to be rendered.
@@ -38,28 +50,27 @@ module Peeky
38
50
  end
39
51
 
40
52
  # Render the class interface
41
- # rubocop:disable Metrics/AbcSize
42
53
  def render
43
54
  @indent = ''
44
- output = []
45
- output.push render_start
55
+ @output = []
56
+ @output.push render_start
46
57
  @indent = ' '
47
- output += render_accessors
48
- output += render_readers
49
- output += render_writers
50
- output += render_methods(@class_info.public_methods)
51
- unless @class_info.private_methods.length.zero?
52
- output += ["#{@indent}private", '']
53
- output += render_methods(@class_info.private_methods)
54
- end
55
- output.pop if output.last == ''
58
+
59
+ render_accessors
60
+ render_readers
61
+ render_writers
62
+
63
+ render_methods(@class_info.public_methods)
64
+ render_class_methods(@class_info.class_methods)
65
+ render_private_methods(@class_info.private_methods)
66
+
67
+ @output.pop if @output.last == ''
56
68
 
57
69
  @indent = ''
58
- output.push render_end
70
+ @output.push render_end
59
71
 
60
- output.join("\n")
72
+ @output.join("\n")
61
73
  end
62
- # rubocop:enable Metrics/AbcSize
63
74
 
64
75
  private
65
76
 
@@ -70,19 +81,19 @@ module Peeky
70
81
  def render_accessors
71
82
  result = @class_info.accessors.map { |attr| "#{@indent}attr_accessor :#{attr.name}" }
72
83
  result.push '' unless result.length.zero?
73
- result
84
+ @output += result
74
85
  end
75
86
 
76
87
  def render_readers
77
88
  result = @class_info.readers.map { |attr| "#{@indent}attr_reader :#{attr.name}" }
78
89
  result.push '' unless result.length.zero?
79
- result
90
+ @output += result
80
91
  end
81
92
 
82
93
  def render_writers
83
94
  result = @class_info.writers.map { |attr| "#{@indent}attr_writer :#{attr.name}" }
84
95
  result.push '' unless result.length.zero?
85
- result
96
+ @output += result
86
97
  end
87
98
 
88
99
  def render_methods(method_list)
@@ -91,7 +102,25 @@ module Peeky
91
102
  "#{@indent}#{render_signature.render}"
92
103
  end
93
104
  result.push '' unless result.length.zero?
94
- result
105
+ @output += result
106
+ end
107
+
108
+ def render_class_methods(methods)
109
+ return if methods.length.zero?
110
+
111
+ @output += ["#{@indent}class << self"]
112
+ @indent += ' '
113
+ @output += render_methods(methods)
114
+ @indent.delete_suffix!(' ')
115
+ @output.pop if @output.last == ''
116
+ @output += ["#{@indent}end", '']
117
+ end
118
+
119
+ def render_private_methods(methods)
120
+ return if methods.length.zero?
121
+
122
+ @output += ["#{@indent}private", '']
123
+ @output += render_methods(methods)
95
124
  end
96
125
 
97
126
  def render_end
@@ -33,26 +33,33 @@ module Peeky
33
33
 
34
34
  # Render the class interface with YARD documentation
35
35
  def render
36
- output = []
37
- output.push render_start
36
+ @output = []
37
+
38
+ render_start
38
39
  @indent += ' '
39
- output += (render_accessors + render_readers + render_writers + render_methods)
40
- output.pop if output.last == ''
40
+
41
+ render_accessors
42
+ render_readers
43
+ render_writers
44
+
45
+ render_public_methods
46
+ render_class_methods
47
+ render_private_methods
48
+
49
+ @output.pop if @output.last == ''
41
50
 
42
51
  @indent = @indent[0..-3]
43
52
 
44
- output.push render_end
53
+ @output.push render_end
45
54
 
46
- output.join("\n")
55
+ @output.join("\n")
47
56
  end
48
57
 
49
58
  private
50
59
 
51
60
  def render_start
52
- [
53
- "#{@indent}# #{@class_info.class_name.titleize.humanize}",
54
- "#{@indent}class #{@class_info.class_name}"
55
- ]
61
+ @output.push "#{@indent}# #{@class_info.class_name.titleize.humanize}"
62
+ @output.push "#{@indent}class #{@class_info.class_name}"
56
63
  end
57
64
 
58
65
  def render_accessors
@@ -63,7 +70,7 @@ module Peeky
63
70
  result.push "#{@indent}attr_accessor :#{attr.name}"
64
71
  end
65
72
  result.push '' unless result.length.zero?
66
- result
73
+ @output += result
67
74
  end
68
75
 
69
76
  def render_readers
@@ -74,7 +81,7 @@ module Peeky
74
81
  result.push "#{@indent}attr_reader :#{attr.name}"
75
82
  end
76
83
  result.push '' unless result.length.zero?
77
- result
84
+ @output += result
78
85
  end
79
86
 
80
87
  def render_writers
@@ -85,23 +92,40 @@ module Peeky
85
92
  result.push "#{@indent}attr_writer :#{attr.name}"
86
93
  end
87
94
  result.push '' unless result.length.zero?
88
- result
95
+ @output += result
89
96
  end
90
97
 
91
- # rubocop:disable Metics/AbcSize
92
- def render_methods
98
+ def render_public_methods
93
99
  result = []
94
100
  class_info.public_methods.map.with_index do |method_signature, index|
95
101
  render_method(result, method_signature, index)
96
102
  end
103
+ result.push '' unless result.length.zero?
104
+ @output += result
105
+ end
106
+
107
+ def render_class_methods
108
+ return if class_info.class_methods.length.zero?
109
+
110
+ result = ["#{@indent}# Class methods", "#{@indent}class << self"]
111
+ @indent += ' '
112
+ class_info.class_methods.map.with_index do |method_signature, index|
113
+ render_method(result, method_signature, index)
114
+ end
115
+ @indent.delete_suffix!(' ')
116
+ result.push "#{@indent}end"
117
+
118
+ @output += result
119
+ end
120
+
121
+ def render_private_methods
122
+ result = []
97
123
  class_info.private_methods.map.with_index do |method_signature, index|
98
124
  result.push "\n#{indent}private\n" if index.zero?
99
125
  render_method(result, method_signature, index)
100
126
  end
101
- result.push '' unless result.length.zero?
102
- result
127
+ @output += result
103
128
  end
104
- # rubocop:enable Metics/AbcSize
105
129
 
106
130
  # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
107
131
  def render_method(result, method_signature, index)
@@ -13,7 +13,8 @@ module Peeky
13
13
 
14
14
  def initialize(method_signature, **opts)
15
15
  # instance_name = opts[:instance_name] || 'instance'
16
- @instance_name = opts[:instance_name]
16
+ @instance_name = opts[:instance_name]
17
+ @class_name = opts[:class_name]
17
18
  @method_signature = method_signature
18
19
  end
19
20
 
@@ -29,11 +30,10 @@ module Peeky
29
30
 
30
31
  params = minimal_call_parameters.length.zero? ? '' : "(#{minimal_call_parameters})"
31
32
 
32
- if @instance_name.nil?
33
- "#{name}#{params}"
34
- else
35
- "#{@instance_name}.#{name}#{params}"
36
- end
33
+ return "#{@instance_name}.#{name}#{params}" unless @instance_name.nil?
34
+ return "#{@class_name}.#{name}#{params}" unless @class_name.nil?
35
+
36
+ "#{name}#{params}"
37
37
  end
38
38
  end
39
39
  end
data/lib/peeky/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Peeky
4
- VERSION = '0.0.42'
4
+ VERSION = '0.0.48'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peeky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.42
4
+ version: 0.0.48
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-01 00:00:00.000000000 Z
11
+ date: 2021-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport