appmap 0.69.0 → 0.70.0

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: 7291177cb4b4c1565130c14731988bc5747f40e63b838b91576d27410820cae5
4
- data.tar.gz: 9026fd2fb37bb292571582d6f0f5c04bb0752ac3683b5bcf120c103e65fed5de
3
+ metadata.gz: 64006e414b4b6cece101a113b5b5359c370b77b96761cfcb02818c07e621d8c5
4
+ data.tar.gz: e7ab888c17031adb8ae993dae863539b32359e967c706b2cc2b13f1f2bb11761
5
5
  SHA512:
6
- metadata.gz: e78dcc4ba973bab886940dabbc87fc01e6e973a097782af9086a38efe415de8a64f422f5b0f9a0a36cd4ff1b33ae94a55b41f3b85f9e95cdc32839b95092ea16
7
- data.tar.gz: c45a0188aa65f1a42c6788fa77ead708e3e2b468af33b9b3603df5c75d5888ed6623940ad1d0f8687bf42ddec6ad202fe8d41dbd862b75a2f87acd0c90472d8b
6
+ metadata.gz: e9b9fbf621b59dfb72875365d2c4485e174b4532b159d62854883e77fd741451f1e8ca4609b0a5323cccc562fcf31ead2ef19923bd3be3e6b0d5d28d5c188635
7
+ data.tar.gz: 4a079f0b5ae28e45a065187e0044446bdbef6a5a91df88f9072b71a825a18c86e3ba6eaf8dc54102b224eb16f3eae1ea0b9e3b8da3958b209bdd9f5d78d0ac50
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # [0.70.0](https://github.com/applandinc/appmap-ruby/compare/v0.69.0...v0.70.0) (2021-12-08)
2
+
3
+
4
+ ### Features
5
+
6
+ * Hook protected methods ([a3722b5](https://github.com/applandinc/appmap-ruby/commit/a3722b504b8e5b8c032988b586b13bdd071fe577))
7
+ * Report sub-packages for nested folders ([dce709b](https://github.com/applandinc/appmap-ruby/commit/dce709b077fd64fc2b34f9abb30a65db529f824b))
8
+
1
9
  # [0.69.0](https://github.com/applandinc/appmap-ruby/compare/v0.68.2...v0.69.0) (2021-12-01)
2
10
 
3
11
 
@@ -76,24 +76,39 @@ module AppMap
76
76
  methods.each do |method|
77
77
  add_function root, method
78
78
  end
79
- root.children.map(&:to_h)
79
+
80
+ collapse_package = lambda do |package|
81
+ return unless package.type == 'package'
82
+
83
+ while package.children.length == 1 && package.children.all? { |child| child.type == 'package' }
84
+ child = package.children[0]
85
+ package.children.clear
86
+ child.children.each { |child| package.children << child }
87
+ package.name = [ package.name, child.name ].join('/')
88
+ end
89
+ package.tap do
90
+ package.children.map(&collapse_package)
91
+ end
92
+ end
93
+
94
+ root.children.map(&collapse_package).map(&:to_h)
80
95
  end
81
96
 
82
97
  protected
83
98
 
84
99
  def add_function(root, method)
85
- object_infos = [
86
- {
87
- name: method.package,
88
- type: 'package'
89
- }
90
- ]
91
- object_infos += method.class_name.split('::').map do |name|
92
- {
93
- name: name,
94
- type: 'class'
95
- }
96
- end
100
+ object_infos = \
101
+ method.package.split('/').map do |name|
102
+ {
103
+ name: name,
104
+ type: 'package'
105
+ }
106
+ end + method.class_name.split('::').map do |name|
107
+ {
108
+ name: name,
109
+ type: 'class'
110
+ }
111
+ end
97
112
  function_info = {
98
113
  name: method.name,
99
114
  type: 'function',
data/lib/appmap/config.rb CHANGED
@@ -44,6 +44,21 @@ module AppMap
44
44
  shallow
45
45
  end
46
46
 
47
+ # Clones this package into a sub-package, if needed.
48
+ # For example, suppose the appmap.yml specifies package `app/models`. If some code in
49
+ # `app/models/dao/user.rb` is mapped, it will be associated with a sub-package
50
+ # `app/models/dao`.
51
+ def subpackage(location, config)
52
+ return self if gem
53
+
54
+ path = location.split('/')[0...-1].join('/')
55
+ clone.tap do |pkg|
56
+ pkg.name = path
57
+ pkg.path = path
58
+ config.packages << pkg
59
+ end
60
+ end
61
+
47
62
  class << self
48
63
  # Builds a package for a path, such as `app/models` in a Rails app. Generally corresponds to a `path:` entry
49
64
  # in appmap.yml. Also used for mapping specific methods via TargetMethods.
@@ -191,7 +206,7 @@ module AppMap
191
206
  }.compact
192
207
 
193
208
  handler_class = hook_decl['handler_class']
194
- options[:handler_class] = Util::class_from_string(handler_class) if handler_class
209
+ options[:handler_class] = Util.class_from_string(handler_class) if handler_class
195
210
 
196
211
  package_hooks(methods, **options)
197
212
  end
@@ -215,7 +230,7 @@ module AppMap
215
230
  builtin = hook_decl['builtin']
216
231
 
217
232
  package_options = {}
218
- package_options[:labels] = Array(labels).map(&:to_s) if labels if labels
233
+ package_options[:labels] = Array(labels).map(&:to_s) if labels
219
234
  package_options[:require_name] = req
220
235
  package_options[:require_name] ||= package if builtin
221
236
  tm = TargetMethods.new(functions, Package.build_from_path(package, **package_options))
@@ -449,13 +464,17 @@ module AppMap
449
464
  return unless location_file
450
465
 
451
466
  location_file = AppMap::Util.normalize_path(location_file)
452
- config
453
- .packages
454
- .select { |pkg| pkg.path }
455
- .find do |pkg|
456
- (location_file.index(pkg.path) == 0) &&
457
- !pkg.exclude.find { |p| location_file.index(p) }
458
- end
467
+
468
+ pkg = config
469
+ .packages
470
+ .select { |pkg| pkg.path }
471
+ .select do |pkg|
472
+ (location_file.index(pkg.path) == 0) &&
473
+ !pkg.exclude.find { |p| location_file.index(p) }
474
+ end
475
+ .min { |a, b| b.path <=> a.path } # Longest matching package first
476
+
477
+ pkg.subpackage(location_file, config) if pkg
459
478
  end
460
479
  end
461
480
 
data/lib/appmap/hook.rb CHANGED
@@ -7,8 +7,10 @@ module AppMap
7
7
  LOG = (ENV['APPMAP_DEBUG'] == 'true' || ENV['DEBUG'] == 'true')
8
8
  LOG_HOOK = (ENV['DEBUG_HOOK'] == 'true')
9
9
 
10
- OBJECT_INSTANCE_METHODS = %i[! != !~ <=> == === =~ __id__ __send__ class clone define_singleton_method display dup enum_for eql? equal? extend freeze frozen? hash inspect instance_eval instance_exec instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method methods nil? object_id private_methods protected_methods public_method public_methods public_send remove_instance_variable respond_to? send singleton_class singleton_method singleton_methods taint tainted? tap then to_enum to_s to_h to_a trust untaint untrust untrusted? yield_self].freeze
11
- OBJECT_STATIC_METHODS = %i[! != !~ < <= <=> == === =~ > >= __id__ __send__ alias_method allocate ancestors attr attr_accessor attr_reader attr_writer autoload autoload? class class_eval class_exec class_variable_defined? class_variable_get class_variable_set class_variables clone const_defined? const_get const_missing const_set constants define_method define_singleton_method deprecate_constant display dup enum_for eql? equal? extend freeze frozen? hash include include? included_modules inspect instance_eval instance_exec instance_method instance_methods instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method method_defined? methods module_eval module_exec name new nil? object_id prepend private_class_method private_constant private_instance_methods private_method_defined? private_methods protected_instance_methods protected_method_defined? protected_methods public_class_method public_constant public_instance_method public_instance_methods public_method public_method_defined? public_methods public_send remove_class_variable remove_instance_variable remove_method respond_to? send singleton_class singleton_class? singleton_method singleton_methods superclass taint tainted? tap then to_enum to_s trust undef_method untaint untrust untrusted? yield_self].freeze
10
+ OBJECT_INSTANCE_METHODS = %i[! != !~ <=> == === =~ __id__ __send__ class clone define_singleton_method display dup
11
+ enum_for eql? equal? extend freeze frozen? hash inspect instance_eval instance_exec instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method methods nil? object_id private_methods protected_methods public_method public_methods public_send remove_instance_variable respond_to? send singleton_class singleton_method singleton_methods taint tainted? tap then to_enum to_s to_h to_a trust untaint untrust untrusted? yield_self].freeze
12
+ OBJECT_STATIC_METHODS = %i[! != !~ < <= <=> == === =~ > >= __id__ __send__ alias_method allocate ancestors attr
13
+ attr_accessor attr_reader attr_writer autoload autoload? class class_eval class_exec class_variable_defined? class_variable_get class_variable_set class_variables clone const_defined? const_get const_missing const_set constants define_method define_singleton_method deprecate_constant display dup enum_for eql? equal? extend freeze frozen? hash include include? included_modules inspect instance_eval instance_exec instance_method instance_methods instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method method_defined? methods module_eval module_exec name new nil? object_id prepend private_class_method private_constant private_instance_methods private_method_defined? private_methods protected_instance_methods protected_method_defined? protected_methods public_class_method public_constant public_instance_method public_instance_methods public_method public_method_defined? public_methods public_send remove_class_variable remove_instance_variable remove_method respond_to? send singleton_class singleton_class? singleton_method singleton_methods superclass taint tainted? tap then to_enum to_s trust undef_method untaint untrust untrusted? yield_self].freeze
12
14
  SLOW_PACKAGE_THRESHOLD = 0.05
13
15
 
14
16
  @unbound_method_arity = ::UnboundMethod.instance_method(:arity)
@@ -29,7 +31,7 @@ module AppMap
29
31
  def already_hooked?(method)
30
32
  # After a method is defined, the statement "module_function <the-method>" can convert that method
31
33
  # into a module (class) method. The method is hooked first when it's defined, then AppMap will attempt to
32
- # hook it again when it's redefined as a module method. So we check the method source location - if it's
34
+ # hook it again when it's redefined as a module method. So we check the method source location - if it's
33
35
  # part of the AppMap source tree, we ignore it.
34
36
  method.source_location && method.source_location[0].index(__dir__) == 0
35
37
  end
@@ -63,7 +65,7 @@ module AppMap
63
65
  @notrace_paths = Set.new
64
66
  # Locations that have already been visited.
65
67
  @trace_locations = Set.new
66
- @module_load_times = Hash.new {|memo,k| memo[k] = 0}
68
+ @module_load_times = Hash.new { |memo, k| memo[k] = 0 }
67
69
  @slow_packages = Set.new
68
70
 
69
71
  if ENV['APPMAP_PROFILE_HOOK'] == 'true'
@@ -90,18 +92,20 @@ module AppMap
90
92
  end
91
93
 
92
94
  # hook_builtins builds hooks for code that is built in to the Ruby standard library.
93
- # No TracePoint events are emitted for builtins, so a separate hooking mechanism is needed.
95
+ # No TracePoint events are emitted for builtins, so a separate hooking mechanism is needed.
94
96
  def hook_builtins
95
97
  return unless self.class.hook_builtins?
96
98
 
97
99
  hook_loaded_code = lambda do |hooks_by_class, builtin|
98
100
  hooks_by_class.each do |class_name, hooks|
99
101
  Array(hooks).each do |hook|
100
- require hook.package.require_name if builtin && hook.package.require_name && hook.package.require_name != 'ruby'
102
+ if builtin && hook.package.require_name && hook.package.require_name != 'ruby'
103
+ require hook.package.require_name
104
+ end
101
105
 
102
106
  Array(hook.method_names).each do |method_name|
103
107
  method_name = method_name.to_sym
104
- base_cls = Util::class_from_string(class_name, must: false)
108
+ base_cls = Util.class_from_string(class_name, must: false)
105
109
  next unless base_cls
106
110
 
107
111
  hook_method = lambda do |entry|
@@ -113,8 +117,10 @@ module AppMap
113
117
 
114
118
  methods = []
115
119
  methods << [ base_cls, base_cls.public_instance_method(method_name) ] rescue nil
120
+ methods << [ base_cls, base_cls.protected_instance_method(method_name) ] rescue nil
116
121
  if base_cls.respond_to?(:singleton_class)
117
122
  methods << [ base_cls.singleton_class, base_cls.singleton_class.public_instance_method(method_name) ] rescue nil
123
+ methods << [ base_cls.singleton_class, base_cls.singleton_class.protected_instance_method(method_name) ] rescue nil
118
124
  end
119
125
  methods.compact!
120
126
  if methods.empty?
@@ -144,19 +150,19 @@ module AppMap
144
150
 
145
151
  path = trace_point.path
146
152
  enabled = !@notrace_paths.member?(path) && config.path_enabled?(path)
147
- if !enabled
148
- warn "Not hooking - path is not enabled" if Hook::LOG || Hook::LOG_HOOK
153
+ unless enabled
154
+ warn 'Not hooking - path is not enabled' if Hook::LOG || Hook::LOG_HOOK
149
155
  @notrace_paths << path
150
156
  return
151
157
  end
152
158
 
153
159
  cls = trace_point.self
154
160
 
155
- instance_methods = cls.public_instance_methods(false) - OBJECT_INSTANCE_METHODS
161
+ instance_methods = cls.public_instance_methods(false) + cls.protected_instance_methods(false) - OBJECT_INSTANCE_METHODS
156
162
  # NoMethodError: private method `singleton_class' called for Rack::MiniProfiler:Class
157
163
  class_methods = begin
158
164
  if cls.respond_to?(:singleton_class)
159
- cls.singleton_class.public_instance_methods(false) - instance_methods - OBJECT_STATIC_METHODS
165
+ cls.singleton_class.public_instance_methods(false) + cls.singleton_class.protected_instance_methods(false) - instance_methods - OBJECT_STATIC_METHODS
160
166
  else
161
167
  []
162
168
  end
@@ -172,12 +178,13 @@ module AppMap
172
178
 
173
179
  next if method_id == :call
174
180
 
175
- method = begin
176
- hook_cls.public_instance_method(method_id)
177
- rescue NameError
178
- warn "AppMap: Method #{hook_cls} #{method.name} is not accessible" if LOG
179
- next
180
- end
181
+ method = \
182
+ begin
183
+ hook_cls.instance_method(method_id)
184
+ rescue NameError
185
+ warn "AppMap: Method #{hook_cls} #{fn} is not accessible: #{$!}" if LOG
186
+ next
187
+ end
181
188
 
182
189
  next if self.class.already_hooked?(method)
183
190
 
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.69.0'
6
+ VERSION = '0.70.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
@@ -16,7 +16,7 @@ describe 'AppMap::ClassMap' do
16
16
  end
17
17
 
18
18
  def ruby_method(method)
19
- AppMap::Trace::RubyMethod.new AppMap::Config::Package.new, method.receiver.class.name, method, false
19
+ AppMap::Trace::RubyMethod.new AppMap::Config::Package.new('pkg'), method.receiver.class.name, method, false
20
20
  end
21
21
 
22
22
  def dig_map(map, depth)
@@ -0,0 +1,7 @@
1
+ module PkgA
2
+ class A
3
+ def self.hello
4
+ 'hello'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ProtectedMethod
4
+ def call_protected
5
+ protected_method
6
+ end
7
+
8
+ def to_s
9
+ 'Protected Method fixture'
10
+ end
11
+
12
+ class << self
13
+ def call_protected
14
+ protected_method
15
+ end
16
+
17
+ protected
18
+
19
+ def protected_method
20
+ 'self.protected'
21
+ end
22
+ end
23
+
24
+ protected
25
+
26
+ def protected_method
27
+ 'protected'
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'pkg_a/a'
2
+
3
+ module SubPackages
4
+ def self.invoke_a
5
+ PkgA::A.hello
6
+ end
7
+ end
data/spec/hook_spec.rb CHANGED
@@ -9,7 +9,7 @@ require 'diffy'
9
9
  # empty. This make some of the expected YAML below easier to
10
10
  # understand.
11
11
  module ShowYamlNulls
12
- def visit_NilClass(o)
12
+ def visit_NilClass(_o)
13
13
  @emitter.scalar('null', nil, 'tag:yaml.org,2002:null', true, false, Psych::Nodes::Scalar::ANY)
14
14
  end
15
15
  end
@@ -18,10 +18,10 @@ Psych::Visitors::YAMLTree.prepend(ShowYamlNulls)
18
18
  describe 'AppMap class Hooking', docker: false do
19
19
  include_context 'collect events'
20
20
 
21
- def invoke_test_file(file, setup: nil, &block)
21
+ def invoke_test_file(file, setup: nil, packages: nil)
22
22
  AppMap.configuration = nil
23
- package = AppMap::Config::Package.build_from_path(file)
24
- config = AppMap::Config.new('hook_spec', packages: [ package ])
23
+ packages ||= [ AppMap::Config::Package.build_from_path(file) ]
24
+ config = AppMap::Config.new('hook_spec', packages: packages)
25
25
  AppMap.configuration = config
26
26
  tracer = nil
27
27
  AppMap::Hook.new(config).enable do
@@ -153,7 +153,7 @@ describe 'AppMap class Hooking', docker: false do
153
153
  class_map = AppMap.class_map(tracer.event_methods).to_yaml
154
154
  expect(Diffy::Diff.new(<<~YAML, class_map).to_s).to eq('')
155
155
  ---
156
- - :name: spec/fixtures/hook/labels.rb
156
+ - :name: spec/fixtures/hook
157
157
  :type: package
158
158
  :children:
159
159
  - :name: ClassWithLabel
@@ -166,7 +166,41 @@ describe 'AppMap class Hooking', docker: false do
166
166
  :labels:
167
167
  - has-fn-label
168
168
  :comment: "# @label has-fn-label\\n"
169
- YAML
169
+ YAML
170
+ end
171
+
172
+ it 'reports sub-folders as distinct packages' do
173
+ _, tracer = invoke_test_file 'spec/fixtures/hook/sub_packages.rb',
174
+ packages: [ AppMap::Config::Package.build_from_path('spec/fixtures/hook') ] do
175
+ SubPackages.invoke_a
176
+ end
177
+ class_map = AppMap.class_map(tracer.event_methods).to_yaml
178
+ expect(Diffy::Diff.new(<<~YAML, class_map).to_s).to eq('')
179
+ ---
180
+ - :name: spec/fixtures/hook
181
+ :type: package
182
+ :children:
183
+ - :name: SubPackages
184
+ :type: class
185
+ :children:
186
+ - :name: invoke_a
187
+ :type: function
188
+ :location: spec/fixtures/hook/sub_packages.rb:4
189
+ :static: true
190
+ - :name: pkg_a
191
+ :type: package
192
+ :children:
193
+ - :name: PkgA
194
+ :type: class
195
+ :children:
196
+ - :name: A
197
+ :type: class
198
+ :children:
199
+ - :name: hello
200
+ :type: function
201
+ :location: spec/fixtures/hook/pkg_a/a.rb:3
202
+ :static: true
203
+ YAML
170
204
  end
171
205
 
172
206
  it 'hooks an instance method that takes no arguments' do
@@ -210,7 +244,7 @@ describe 'AppMap class Hooking', docker: false do
210
244
  class_map = AppMap.class_map(tracer.event_methods).to_yaml
211
245
  expect(Diffy::Diff.new(<<~YAML, class_map).to_s).to eq('')
212
246
  ---
213
- - :name: spec/fixtures/hook/instance_method.rb
247
+ - :name: spec/fixtures/hook
214
248
  :type: package
215
249
  :children:
216
250
  - :name: InstanceMethod
@@ -243,6 +277,92 @@ describe 'AppMap class Hooking', docker: false do
243
277
  end
244
278
  end
245
279
 
280
+ it 'records protected instance methods' do
281
+ events_yaml = <<~YAML
282
+ ---
283
+ - :id: 1
284
+ :event: :call
285
+ :defined_class: ProtectedMethod
286
+ :method_id: call_protected
287
+ :path: spec/fixtures/hook/protected_method.rb
288
+ :lineno: 4
289
+ :static: false
290
+ :parameters: []
291
+ :receiver:
292
+ :class: ProtectedMethod
293
+ :value: Protected Method fixture
294
+ - :id: 2
295
+ :event: :call
296
+ :defined_class: ProtectedMethod
297
+ :method_id: protected_method
298
+ :path: spec/fixtures/hook/protected_method.rb
299
+ :lineno: 26
300
+ :static: false
301
+ :parameters: []
302
+ :receiver:
303
+ :class: ProtectedMethod
304
+ :value: Protected Method fixture
305
+ - :id: 3
306
+ :event: :return
307
+ :parent_id: 2
308
+ :return_value:
309
+ :class: String
310
+ :value: protected
311
+ - :id: 4
312
+ :event: :return
313
+ :parent_id: 1
314
+ :return_value:
315
+ :class: String
316
+ :value: protected
317
+ YAML
318
+ test_hook_behavior 'spec/fixtures/hook/protected_method.rb', events_yaml do
319
+ expect(ProtectedMethod.new.call_protected).to eq('protected')
320
+ end
321
+ end
322
+
323
+ it 'records protected singleton (static) methods' do
324
+ events_yaml = <<~YAML
325
+ ---
326
+ - :id: 1
327
+ :event: :call
328
+ :defined_class: ProtectedMethod
329
+ :method_id: call_protected
330
+ :path: spec/fixtures/hook/protected_method.rb
331
+ :lineno: 13
332
+ :static: true
333
+ :parameters: []
334
+ :receiver:
335
+ :class: Class
336
+ :value: ProtectedMethod
337
+ - :id: 2
338
+ :event: :call
339
+ :defined_class: ProtectedMethod
340
+ :method_id: protected_method
341
+ :path: spec/fixtures/hook/protected_method.rb
342
+ :lineno: 19
343
+ :static: true
344
+ :parameters: []
345
+ :receiver:
346
+ :class: Class
347
+ :value: ProtectedMethod
348
+ - :id: 3
349
+ :event: :return
350
+ :parent_id: 2
351
+ :return_value:
352
+ :class: String
353
+ :value: self.protected
354
+ - :id: 4
355
+ :event: :return
356
+ :parent_id: 1
357
+ :return_value:
358
+ :class: String
359
+ :value: self.protected
360
+ YAML
361
+ test_hook_behavior 'spec/fixtures/hook/protected_method.rb', events_yaml do
362
+ expect(ProtectedMethod.call_protected).to eq('self.protected')
363
+ end
364
+ end
365
+
246
366
  it 'hooks an instance method that takes an argument' do
247
367
  events_yaml = <<~YAML
248
368
  ---
@@ -483,7 +603,6 @@ describe 'AppMap class Hooking', docker: false do
483
603
  end
484
604
  end
485
605
 
486
-
487
606
  it 'hooks an included method' do
488
607
  events_yaml = <<~YAML
489
608
  ---
@@ -607,11 +726,9 @@ describe 'AppMap class Hooking', docker: false do
607
726
  :lineno: 9
608
727
  YAML
609
728
  test_hook_behavior 'spec/fixtures/hook/exception_method.rb', events_yaml do
610
- begin
611
- ExceptionMethod.new.raise_exception
612
- rescue
613
- # don't let the exception fail the test
614
- end
729
+ ExceptionMethod.new.raise_exception
730
+ rescue
731
+ # don't let the exception fail the test
615
732
  end
616
733
  end
617
734
 
@@ -639,16 +756,13 @@ describe 'AppMap class Hooking', docker: false do
639
756
  :lineno: 59
640
757
  YAML
641
758
  test_hook_behavior 'spec/fixtures/hook/exception_method.rb', events_yaml do
642
- begin
643
- ExceptionMethod.new.raise_illegal_utf8_message
644
- rescue
645
- # don't let the exception fail the test
646
- end
759
+ ExceptionMethod.new.raise_illegal_utf8_message
760
+ rescue
761
+ # don't let the exception fail the test
647
762
  end
648
763
  end
649
764
 
650
765
  context 'string conversions works for the receiver when' do
651
-
652
766
  it 'is missing #to_s' do
653
767
  events_yaml = <<~YAML
654
768
  ---
@@ -979,7 +1093,7 @@ describe 'AppMap class Hooking', docker: false do
979
1093
  end
980
1094
  end
981
1095
 
982
- it "preserves the arity of hooked methods" do
1096
+ it 'preserves the arity of hooked methods' do
983
1097
  invoke_test_file 'spec/fixtures/hook/instance_method.rb' do
984
1098
  expect(InstanceMethod.instance_method(:say_echo).arity).to be(1)
985
1099
  expect(InstanceMethod.new.method(:say_echo).arity).to be(1)
@@ -157,31 +157,31 @@ describe 'Rails' do
157
157
  )
158
158
 
159
159
  expect(appmap['classMap']).to include hash_including(
160
- 'name' => 'app/views',
160
+ 'name' => 'app',
161
161
  'children' => include(hash_including(
162
- 'name' => 'app_views_users_index_html_haml',
162
+ 'name' => 'views',
163
163
  'children' => include(hash_including(
164
- 'name' => 'render',
165
- 'type' => 'function',
166
- 'location' => 'app/views/users/index.html.haml',
167
- 'static' => true,
168
- 'labels' => [ 'mvc.template' ]
169
- ))
170
- ))
171
- )
164
+ 'name' => 'app_views_users_index_html_haml',
165
+ 'children' => include(hash_including(
166
+ 'name' => 'render',
167
+ 'type' => 'function',
168
+ 'location' => 'app/views/users/index.html.haml',
169
+ 'static' => true,
170
+ 'labels' => [ 'mvc.template' ]
171
+ )))))))
172
172
  expect(appmap['classMap']).to include hash_including(
173
- 'name' => 'app/views',
173
+ 'name' => 'app',
174
174
  'children' => include(hash_including(
175
- 'name' => 'app_views_layouts_application_html_haml',
175
+ 'name' => 'views',
176
176
  'children' => include(hash_including(
177
- 'name' => 'render',
178
- 'type' => 'function',
179
- 'location' => 'app/views/layouts/application.html.haml',
180
- 'static' => true,
181
- 'labels' => [ 'mvc.template' ]
182
- ))
183
- ))
184
- )
177
+ 'name' => 'app_views_layouts_application_html_haml',
178
+ 'children' => include(hash_including(
179
+ 'name' => 'render',
180
+ 'type' => 'function',
181
+ 'location' => 'app/views/layouts/application.html.haml',
182
+ 'static' => true,
183
+ 'labels' => [ 'mvc.template' ]
184
+ )))))))
185
185
  end
186
186
  end
187
187
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.69.0
4
+ version: 0.70.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Gilpin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-01 00:00:00.000000000 Z
11
+ date: 2021-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -3506,10 +3506,13 @@ files:
3506
3506
  - spec/fixtures/hook/kwargs.rb
3507
3507
  - spec/fixtures/hook/labels.rb
3508
3508
  - spec/fixtures/hook/method_named_call.rb
3509
+ - spec/fixtures/hook/pkg_a/a.rb
3510
+ - spec/fixtures/hook/protected_method.rb
3509
3511
  - spec/fixtures/hook/revoke_api_key.appmap.json
3510
3512
  - spec/fixtures/hook/singleton_method.rb
3511
3513
  - spec/fixtures/hook/spec/api_spec.rb
3512
3514
  - spec/fixtures/hook/spec/user_spec.rb
3515
+ - spec/fixtures/hook/sub_packages.rb
3513
3516
  - spec/fixtures/hook/user_page_scenario.appmap.json
3514
3517
  - spec/fixtures/rack_users_app/.dockerignore
3515
3518
  - spec/fixtures/rack_users_app/.gitignore