peeky 0.0.42 → 0.0.48

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