appmap 0.73.0 → 0.76.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: df9ed913bb9ce4b945312ab2a50d8305b7c85c8f84a2004b9cf785362fcf2ad2
4
- data.tar.gz: 2f2a844c20263b62a1291b05396d883c205cdebf2ae32062206e7bf42c23e757
3
+ metadata.gz: 15371b6980bcc95640c4d579c323da11db85509c0f50110c318da0d9cc04f189
4
+ data.tar.gz: 03a4e889edcfaf15629a7e9662f230df18b3b1123c86ce463edf4ba03c9e7280
5
5
  SHA512:
6
- metadata.gz: 330bcbec5db0a2b92662898432b3cc4eb4e8ca98729f6cfc0577d6490a0f19a1908e19b6c58c512c9b5db7e98a9f90804c5f0fe4362f52b31a69849760cde6db
7
- data.tar.gz: 29544bb8ae0db136aad8a518511eb6723fe113e54bc4d585d9e06a857f9227f3e0fbf6daa2bcf1067df5092eef88b13034862d09b187e496cb6758eb8ec094eb
6
+ metadata.gz: a1bc1b230b3e946400acbc3d1bc8ee87508973ce594ca488c17f2d39d1280346959e2c5acb5c9d3f6cd62627b61764f5cd0d96ef60639c645337df2ac850409b
7
+ data.tar.gz: e0bb0223a99795cedc38470d49dae428a720f0638674dc4e04b26d15aa085286d51c42aacc1ee490ff713122711728af9df1064adcb66a6dff7ccb89292b72a5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ # [0.76.0](https://github.com/applandinc/appmap-ruby/compare/v0.75.0...v0.76.0) (2022-03-19)
2
+
3
+
4
+ ### Features
5
+
6
+ * Autoload hook handlers ([4cc0e70](https://github.com/applandinc/appmap-ruby/commit/4cc0e7003a8c37d3b6c8c8bbc68cffac0335b878))
7
+
8
+ # [0.75.0](https://github.com/applandinc/appmap-ruby/compare/v0.74.0...v0.75.0) (2022-03-17)
9
+
10
+
11
+ ### Features
12
+
13
+ * Apply label deserialize.safe to ActiveSupport.run_load_hooks ([1f67f9b](https://github.com/applandinc/appmap-ruby/commit/1f67f9b260503772cba6824ef746f903def14323))
14
+ * Print stacks if requested by env var ([72ef911](https://github.com/applandinc/appmap-ruby/commit/72ef9116d3248467632762ce63303a54bed998e9))
15
+
16
+ # [0.74.0](https://github.com/applandinc/appmap-ruby/compare/v0.73.0...v0.74.0) (2022-03-14)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * Apply special case hook handling to Kernel and instance_eval ([25823ff](https://github.com/applandinc/appmap-ruby/commit/25823ff0fb86beff3edc64da251a125ee198ef40))
22
+ * Only apply a method hook to a class that defines the method ([ede2236](https://github.com/applandinc/appmap-ruby/commit/ede22364bfcbf324e8db3aa6d64d5b032f36ace2))
23
+ * Optimize/improve string-ification of values ([c9b6cdb](https://github.com/applandinc/appmap-ruby/commit/c9b6cdb72dfc55cc3a166eda470eba19093e9090))
24
+
25
+
26
+ ### Features
27
+
28
+ * Improve hook performance by using bind_call ([e09fce9](https://github.com/applandinc/appmap-ruby/commit/e09fce9f5b3c0b18bc3b81083c1523df6a6932db))
29
+ * Label system.exec, string.pack, string.html_safe ([963c6dd](https://github.com/applandinc/appmap-ruby/commit/963c6ddfa0f607ad219ae8829cfb383b0d5988d0))
30
+ * Log initiation of each builtin hook ([902a736](https://github.com/applandinc/appmap-ruby/commit/902a7360d17c6b49de97f34643c733e8c47c294d))
31
+
1
32
  # [0.73.0](https://github.com/applandinc/appmap-ruby/compare/v0.72.5...v0.73.0) (2022-03-07)
2
33
 
3
34
 
@@ -0,0 +1,13 @@
1
+ - methods:
2
+ - Open3#capture2
3
+ - Open3#capture2e
4
+ - Open3#capture3
5
+ - Open3#pipeline
6
+ - Open3#pipeline_r
7
+ - Open3#pipeline_rw
8
+ - Open3#pipeline_start
9
+ - Open3#pipeline_w
10
+ - Open3#popen2
11
+ - Open3#popen2e
12
+ - Open3#popen3
13
+ label: system.exec
@@ -0,0 +1,39 @@
1
+ - methods:
2
+ - Marshal#load
3
+ - Marshal#restore
4
+ require_name: ruby
5
+ label: deserialize.unsafe
6
+ - method: Marshal#dump
7
+ require_name: ruby
8
+ label: serialize
9
+ - method: String#pack
10
+ require_name: ruby
11
+ label: string.pack
12
+ - methods:
13
+ - String#unpack
14
+ - String#unpack1
15
+ require_name: ruby
16
+ label: string.unpack
17
+ #- methods:
18
+ # TODO: eval does not happen in the right context, and therefore any new constants
19
+ # which are defined are placed on the wrong module/class.
20
+ # - Kernel#eval
21
+ # - Binding#eval
22
+ # - BasicObject#instance_eval
23
+ # These methods cannot be hooked as far as I can tell.
24
+ # Why? When calling one of these functions, the context at the point of
25
+ # definition is used. It's not possible to bind class_eval to a new context.
26
+ # - Module#class_eval
27
+ # - Module#module_eval
28
+ # require_name: ruby
29
+ # label: lang.eval
30
+ - methods:
31
+ - IO#popen
32
+ - Kernel#exec
33
+ - Kernel#spawn
34
+ - Kernel#syscall
35
+ - Kernel#system
36
+ - Process#exec
37
+ - Process#spawn
38
+ require_name: ruby
39
+ label: system.exec
data/lib/appmap/config.rb CHANGED
@@ -4,8 +4,7 @@ require 'pathname'
4
4
  require 'set'
5
5
  require 'yaml'
6
6
  require 'appmap/util'
7
- require 'appmap/handler/net_http'
8
- require 'appmap/handler/rails/template'
7
+ require 'appmap/handler'
9
8
  require 'appmap/service/guesser'
10
9
  require 'appmap/swagger/configuration'
11
10
  require 'appmap/depends/configuration'
@@ -206,8 +205,8 @@ module AppMap
206
205
  }.compact
207
206
 
208
207
  handler_class = hook_decl['handler_class']
209
- options[:handler_class] = Util.class_from_string(handler_class) if handler_class
210
-
208
+ options[:handler_class] = Handler.find(handler_class) if handler_class
209
+
211
210
  package_hooks(methods, **options)
212
211
  end
213
212
 
@@ -51,7 +51,7 @@ module AppMap
51
51
  appmap['metadata'] = update_metadata(scenario, appmap['metadata'])
52
52
  scenario_filename = AppMap::Util.scenario_filename(appmap['metadata']['name'])
53
53
 
54
- AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, scenario_filename), JSON.generate(appmap))
54
+ AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, scenario_filename), appmap)
55
55
  end
56
56
 
57
57
  def enabled?
data/lib/appmap/event.rb CHANGED
@@ -20,7 +20,9 @@ module AppMap
20
20
  MethodEventStruct = Struct.new(:id, :event, :thread_id)
21
21
 
22
22
  class MethodEvent < MethodEventStruct
23
- LIMIT = 100
23
+ MAX_ARRAY_ENUMERATION = 10
24
+ MAX_HASH_ENUMERATION = 10
25
+ MAX_STRING_LENGTH = 100
24
26
 
25
27
  class << self
26
28
  def build_from_invocation(event_type, event:)
@@ -48,14 +50,14 @@ module AppMap
48
50
  end
49
51
 
50
52
  start = Time.now
51
- value_string = custom_display_string(value) || default_display_string(value)
53
+ value_string, final = custom_display_string(value) || default_display_string(value)
52
54
 
53
55
  if @times
54
56
  elapsed = Time.now - start
55
57
  @times[best_class_name(value)] += elapsed
56
58
  end
57
59
 
58
- encode_display_string(value_string)
60
+ final ? value_string : encode_display_string(value_string)
59
61
  end
60
62
 
61
63
  def object_properties(hash_like)
@@ -80,21 +82,33 @@ module AppMap
80
82
  end
81
83
 
82
84
  def encode_display_string(value)
83
- (value||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
85
+ (value||'')[0...MAX_STRING_LENGTH].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
84
86
  end
85
87
 
86
88
  def custom_display_string(value)
87
89
  case value
88
90
  when NilClass, TrueClass, FalseClass, Numeric, Time, Date
89
- value.to_s
91
+ [ value.to_s, true ]
92
+ when Symbol
93
+ [ ":#{value}", true ]
90
94
  when String
91
- value[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
95
+ result = value[0...MAX_STRING_LENGTH].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
96
+ result << " (...#{value.length - MAX_STRING_LENGTH} more characters)" if value.length > MAX_STRING_LENGTH
97
+ [ result, true ]
98
+ when Array
99
+ result = value[0...MAX_ARRAY_ENUMERATION].map{|v| display_string(v)}.join(', ')
100
+ result << " (...#{value.length - MAX_ARRAY_ENUMERATION} more items)" if value.length > MAX_ARRAY_ENUMERATION
101
+ [ [ '[', result, ']' ].join, true ]
102
+ when Hash
103
+ result = value.keys[0...MAX_HASH_ENUMERATION].map{|key| "#{display_string(key)}=>#{display_string(value[key])}"}.join(', ')
104
+ result << " (...#{value.size - MAX_HASH_ENUMERATION} more entries)" if value.size > MAX_HASH_ENUMERATION
105
+ [ [ '{', result, '}' ].join, true ]
92
106
  when File
93
- "#{value.class}[path=#{value.path}]"
107
+ [ "#{value.class}[path=#{value.path}]", true ]
94
108
  when Net::HTTP
95
- "#{value.class}[#{value.address}:#{value.port}]"
109
+ [ "#{value.class}[#{value.address}:#{value.port}]", true ]
96
110
  when Net::HTTPGenericRequest
97
- "#{value.class}[#{value.method} #{value.path}]"
111
+ [ "#{value.class}[#{value.method} #{value.path}]", true ]
98
112
  end
99
113
  rescue StandardError
100
114
  nil
@@ -11,3 +11,7 @@
11
11
  label: mvc.template.resolver
12
12
  handler_class: AppMap::Handler::Rails::Template::ResolverHandler
13
13
  require_name: action_view
14
+ - methods:
15
+ - ActionView::Helpers::SanitizeHelper#sanitize
16
+ label: string.html_safe
17
+ require_name: action_view
@@ -10,3 +10,7 @@
10
10
  label: crypto.secure_compare
11
11
  require_name: active_support/security_utils
12
12
  force: true
13
+ - method: ActiveSupport.run_load_hooks
14
+ label: deserialize.safe
15
+ require_name: active_support/lazy_load_hooks
16
+ force: true
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/inflector/methods'
4
+
5
+ module AppMap
6
+ # Specific hook handler classes and general related utilities.
7
+ module Handler
8
+ # Try to find handler module with a given name.
9
+ #
10
+ # If the module is not loaded, tries to require the appropriate file
11
+ # using the usual conventions, eg. `Acme::Handler::AppMap` will try
12
+ # to require `acme/handler/app_map`, then `acme/handler` and
13
+ # finally `acme`. Raises NameError if the module could not be loaded
14
+ # this way.
15
+ def self.find(name)
16
+ begin
17
+ return Object.const_get name
18
+ rescue NameError
19
+ try_load ActiveSupport::Inflector.underscore name
20
+ end
21
+ Object.const_get name
22
+ end
23
+
24
+ def self.try_load(fname)
25
+ fname = fname.sub %r{^app_map/}, 'appmap/'
26
+ fname = fname.split '/'
27
+ until fname.empty?
28
+ begin
29
+ require fname.join '/'
30
+ return
31
+ rescue LoadError
32
+ # pass
33
+ end
34
+ fname.pop
35
+ end
36
+ end
37
+ end
38
+ end
@@ -69,28 +69,24 @@ module AppMap
69
69
  after_hook = self.method(:after_hook)
70
70
  with_disabled_hook = self.method(:with_disabled_hook)
71
71
 
72
- hook_method_def = Proc.new do |*args, &block|
73
- is_array_containing_empty_hash = ->(obj) {
74
- obj.is_a?(Array) && obj.length == 1 && obj[0].is_a?(Hash) && obj[0].size == 0
75
- }
76
-
77
- call_instance_method = -> {
78
- # https://github.com/applandinc/appmap-ruby/issues/153
79
- if NEW_RUBY && is_array_containing_empty_hash.(args) && hook_method.arity == 1
80
- if NEW_RUBY
81
- hook_method.bind_call(self, {}, &block)
82
- else
83
- hook_method.bind(self).call({}, &block)
84
- end
72
+ is_array_containing_empty_hash = ->(obj) {
73
+ obj.is_a?(Array) && obj.length == 1 && obj[0].is_a?(Hash) && obj[0].size == 0
74
+ }
75
+
76
+ call_instance_method = lambda do |receiver, args, &block|
77
+ # https://github.com/applandinc/appmap-ruby/issues/153
78
+ if NEW_RUBY && is_array_containing_empty_hash.(args) && hook_method.arity == 1
79
+ hook_method.bind_call(receiver, {}, &block)
80
+ else
81
+ if NEW_RUBY
82
+ hook_method.bind_call(receiver, *args, &block)
85
83
  else
86
- if NEW_RUBY
87
- hook_method.bind_call(self, *args, &block)
88
- else
89
- hook_method.bind(self).call(*args, &block)
90
- end
84
+ hook_method.bind(receiver).call(*args, &block)
91
85
  end
92
- }
86
+ end
87
+ end
93
88
 
89
+ hook_method_def = Proc.new do |*args, &block|
94
90
  # We may not have gotten the class for the method during
95
91
  # initialization (e.g. for a singleton method on an embedded
96
92
  # struct), so make sure we have it now.
@@ -102,7 +98,9 @@ module AppMap
102
98
 
103
99
  enabled = true if AppMap.tracing.enabled? && !reentrant && !disabled_by_shallow_flag.call
104
100
 
105
- return call_instance_method.call unless enabled
101
+ enabled = false if %i[instance_eval instance_exec].member?(hook_method.name) && args.empty?
102
+
103
+ return call_instance_method.call(self, args, &block) unless enabled
106
104
 
107
105
  call_event, start_time = with_disabled_hook.call do
108
106
  before_hook.call(self, defined_class, args)
@@ -110,7 +108,7 @@ module AppMap
110
108
  return_value = nil
111
109
  exception = nil
112
110
  begin
113
- return_value = call_instance_method.call
111
+ return_value = call_instance_method.call(self, args, &block)
114
112
  rescue
115
113
  exception = $ERROR_INFO
116
114
  raise
@@ -125,8 +123,18 @@ module AppMap
125
123
  hook_method_parameters = hook_method.parameters.dup.freeze
126
124
  SIGNATURES[[ hook_class, hook_method.name ]] = hook_method_parameters
127
125
 
128
- hook_class.ancestors.first.tap do |cls|
129
- cls.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
126
+ # irb(main):001:0> Kernel.public_instance_method(:system)
127
+ # (irb):1:in `public_instance_method': method `system' for module `Kernel' is private (NameError)
128
+ if hook_class == Kernel
129
+ hook_class.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
130
+ else
131
+ hook_class.ancestors.find { |cls| cls.method_defined?(hook_method.name, false) }.tap do |cls|
132
+ if cls
133
+ cls.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
134
+ else
135
+ warn "#{hook_method.name} not found on #{hook_class}"
136
+ end
137
+ end
130
138
  end
131
139
  end
132
140
 
data/lib/appmap/hook.rb CHANGED
@@ -105,8 +105,14 @@ module AppMap
105
105
 
106
106
  Array(hook.method_names).each do |method_name|
107
107
  method_name = method_name.to_sym
108
- base_cls = Util.class_from_string(class_name, must: false)
109
- next unless base_cls
108
+
109
+ warn "AppMap: Initiating hook for builtin #{class_name} #{method_name}" if LOG
110
+
111
+ begin
112
+ base_cls = Object.const_get class_name
113
+ rescue NameError
114
+ next
115
+ end
110
116
 
111
117
  hook_method = lambda do |entry|
112
118
  cls, method = entry
@@ -116,6 +122,11 @@ module AppMap
116
122
  end
117
123
 
118
124
  methods = []
125
+ # irb(main):001:0> Kernel.public_instance_method(:system)
126
+ # (irb):1:in `public_instance_method': method `system' for module `Kernel' is private (NameError)
127
+ if base_cls == Kernel
128
+ methods << [ base_cls, base_cls.instance_method(method_name) ] rescue nil
129
+ end
119
130
  methods << [ base_cls, base_cls.public_instance_method(method_name) ] rescue nil
120
131
  methods << [ base_cls, base_cls.protected_instance_method(method_name) ] rescue nil
121
132
  if base_cls.respond_to?(:singleton_class)
@@ -120,7 +120,7 @@ module AppMap
120
120
  }.compact
121
121
  fname = AppMap::Util.scenario_filename(name)
122
122
 
123
- AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, fname), JSON.generate(appmap))
123
+ AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, fname), appmap)
124
124
  end
125
125
 
126
126
  def enabled?
data/lib/appmap/record.rb CHANGED
@@ -23,5 +23,5 @@ at_exit do
23
23
  'classMap' => AppMap.class_map(tracer.event_methods),
24
24
  'events' => events
25
25
  }
26
- AppMap::Util.write_appmap('appmap.json', JSON.generate(appmap))
26
+ AppMap::Util.write_appmap('appmap.json', appmap)
27
27
  end
data/lib/appmap/rspec.rb CHANGED
@@ -205,7 +205,7 @@ module AppMap
205
205
  }.compact
206
206
  fname = AppMap::Util.scenario_filename(name)
207
207
 
208
- AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, fname), JSON.generate(appmap))
208
+ AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, fname), appmap)
209
209
  end
210
210
 
211
211
  def enabled?
data/lib/appmap/trace.rb CHANGED
@@ -84,12 +84,43 @@ module AppMap
84
84
  end
85
85
  end
86
86
 
87
+ class StackPrinter
88
+ class << self
89
+ def enabled?
90
+ ENV['APPMAP_PRINT_STACKS'] == 'true'
91
+ end
92
+
93
+ def depth
94
+ (ENV['APPMAP_STACK_DEPTH'] || 20).to_i
95
+ end
96
+ end
97
+
98
+ def initialize
99
+ @@stacks ||= Hash.new
100
+ end
101
+
102
+ def record(event)
103
+ stack = caller.select { |line| !line.index('/lib/appmap/') }[0...StackPrinter.depth].join("\n ")
104
+ stack_hash = Digest::SHA256.hexdigest(stack)
105
+ unless @@stacks[stack_hash]
106
+ @@stacks[stack_hash] = stack
107
+ puts
108
+ puts 'Event: ' + event.to_h.map { |k, v| [ "#{k}: #{v}" ] }.join(", ")
109
+ puts ' ' + stack
110
+ puts
111
+ end
112
+ end
113
+ end
114
+
87
115
  class Tracer
116
+ attr_accessor :stacks
117
+
88
118
  # Records the events which happen in a program.
89
119
  def initialize
90
120
  @events = []
91
121
  @last_package_for_thread = {}
92
122
  @methods = Set.new
123
+ @stack_printer = StackPrinter.new if StackPrinter.enabled?
93
124
  @enabled = false
94
125
  end
95
126
 
@@ -112,6 +143,7 @@ module AppMap
112
143
  def record_event(event, package: nil, defined_class: nil, method: nil)
113
144
  return unless @enabled
114
145
 
146
+ @stack_printer.record(event) if @stack_printer
115
147
  @last_package_for_thread[Thread.current.object_id] = package if package
116
148
  @events << event
117
149
  static = event.static if event.respond_to?(:static)
data/lib/appmap/util.rb CHANGED
@@ -21,14 +21,6 @@ module AppMap
21
21
  WHITE = "\e[37m"
22
22
 
23
23
  class << self
24
- def class_from_string(fq_class, must: true)
25
- fq_class.split('::').inject(Object) do |mod, class_name|
26
- mod.const_get(class_name)
27
- end
28
- rescue NameError
29
- raise if must
30
- end
31
-
32
24
  def parse_function_name(name)
33
25
  package_tokens = name.split('/')
34
26
 
@@ -171,7 +163,7 @@ module AppMap
171
163
  mode = File::RDWR | File::CREAT | File::EXCL
172
164
  ::Dir::Tmpname.create([ 'appmap_', '.json' ]) do |tmpname|
173
165
  tempfile = File.open(tmpname, mode)
174
- tempfile.write(appmap)
166
+ tempfile.write(JSON.generate(appmap))
175
167
  tempfile.close
176
168
  # Atomically move the tempfile into place.
177
169
  FileUtils.mv tempfile.path, filename
@@ -3,7 +3,7 @@
3
3
  module AppMap
4
4
  URL = 'https://github.com/applandinc/appmap-ruby'
5
5
 
6
- VERSION = '0.73.0'
6
+ VERSION = '0.76.0'
7
7
 
8
8
  APPMAP_FORMAT_VERSION = '1.5.1'
9
9
 
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'appmap/event'
5
+
6
+ include AppMap
7
+
8
+ describe 'display_string' do
9
+ def display_string(value)
10
+ Event::MethodEvent.display_string value
11
+ end
12
+
13
+ def compare_display_string(value, expected)
14
+ expect(display_string(value)).to eq(expected)
15
+ end
16
+
17
+ context 'for a' do
18
+ it 'String' do
19
+ compare_display_string 'foo', 'foo'
20
+ end
21
+ it 'long String' do
22
+ compare_display_string 'foo' * 100, 'foo' * 33 + 'f (...200 more characters)'
23
+ end
24
+ it 'Array' do
25
+ compare_display_string([ 1, 'my', :bar, [ 2, 3 ], { 4 => 5 } ], '[1, my, :bar, [2, 3], {4=>5}]')
26
+ end
27
+ it 'large Array' do
28
+ compare_display_string 50.times.map { |i| i }, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9 (...40 more items)]'
29
+ end
30
+ it 'large Hash' do
31
+ compare_display_string(50.times.map { |i| [ i*2, i*2+1] }.to_h, '{0=>1, 2=>3, 4=>5, 6=>7, 8=>9, 10=>11, 12=>13, 14=>15, 16=>17, 18=>19 (...40 more entries)}')
32
+ end
33
+ it 'Hash' do
34
+ compare_display_string({ 1 => 2, 'my' => 'neighbor', bar: :baz, ary: [ 1, 2 ]}, '{1=>2, my=>neighbor, :bar=>:baz, :ary=>[1, 2]}')
35
+ end
36
+ it 'big Hash' do
37
+ compare_display_string(50.times.map { |i| [ i*2, i*2+1] }.to_h, '{0=>1, 2=>3, 4=>5, 6=>7, 8=>9, 10=>11, 12=>13, 14=>15, 16=>17, 18=>19 (...40 more entries)}')
38
+ end
39
+ end
40
+ end
data/spec/hook_spec.rb CHANGED
@@ -1136,7 +1136,7 @@ describe 'AppMap class Hooking', docker: false do
1136
1136
  :parameters:
1137
1137
  - :name: :args
1138
1138
  :class: Array
1139
- :value: '["foo"]'
1139
+ :value: "[foo]"
1140
1140
  :kind: :rest
1141
1141
  - :name: :kw1
1142
1142
  :class: String
@@ -78,7 +78,7 @@ describe 'Rails' do
78
78
  'name' => 'params',
79
79
  'class' => 'ActiveSupport::HashWithIndifferentAccess',
80
80
  'object_id' => Integer,
81
- 'value' => '{"login"=>"alice"}',
81
+ 'value' => '{login=>alice}',
82
82
  'kind' => 'req'
83
83
  ),
84
84
  'receiver' => anything
@@ -127,7 +127,7 @@ describe 'Net::HTTP handler' do
127
127
  :message:
128
128
  - :name: ary
129
129
  :class: Array
130
- :value: '["1", "2"]'
130
+ :value: "[1, 2]"
131
131
  EVENT
132
132
  end
133
133
 
data/test/gem_test.rb CHANGED
@@ -24,7 +24,7 @@ class GemTest < Minitest::Test
24
24
  appmap_file = 'tmp/appmap/minitest/Parser_parser.appmap.json'
25
25
  appmap = JSON.parse(File.read(appmap_file))
26
26
  events = appmap['events']
27
- assert_equal 2, events.size
27
+ assert_equal 6, events.size
28
28
  assert_equal 'call', events.first['event']
29
29
  assert_equal 'default_parser', events.first['method_id']
30
30
  assert_match /\lib\/parser\/base\.rb$/, events.first['path']
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.73.0
4
+ version: 0.76.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: 2022-03-07 00:00:00.000000000 Z
11
+ date: 2022-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -339,10 +339,11 @@ files:
339
339
  - lib/appmap/agent.rb
340
340
  - lib/appmap/builtin_hooks/json.yml
341
341
  - lib/appmap/builtin_hooks/logger.yml
342
- - lib/appmap/builtin_hooks/marshal.yml
343
342
  - lib/appmap/builtin_hooks/net/http.yml
343
+ - lib/appmap/builtin_hooks/open3.yml
344
344
  - lib/appmap/builtin_hooks/openssl.yml
345
345
  - lib/appmap/builtin_hooks/psych.yml
346
+ - lib/appmap/builtin_hooks/ruby.yml
346
347
  - lib/appmap/class_map.rb
347
348
  - lib/appmap/command/agent_setup/init.rb
348
349
  - lib/appmap/command/agent_setup/status.rb
@@ -373,6 +374,7 @@ files:
373
374
  - lib/appmap/gem_hooks/resque.yml
374
375
  - lib/appmap/gem_hooks/sidekiq.yml
375
376
  - lib/appmap/gem_hooks/sprockets.yml
377
+ - lib/appmap/handler.rb
376
378
  - lib/appmap/handler/function.rb
377
379
  - lib/appmap/handler/net_http.rb
378
380
  - lib/appmap/handler/rails/request_handler.rb
@@ -409,6 +411,7 @@ files:
409
411
  - spec/config_spec.rb
410
412
  - spec/depends/api_spec.rb
411
413
  - spec/depends/spec_helper.rb
414
+ - spec/display_string_spec.rb
412
415
  - spec/fixtures/config/incomplete_config.yml
413
416
  - spec/fixtures/config/invalid_config.yml
414
417
  - spec/fixtures/config/invalid_yaml_config.yml
@@ -1,8 +0,0 @@
1
- - methods:
2
- - Marshal#load
3
- - Marshal#restore
4
- require_name: ruby
5
- label: deserialize.unsafe
6
- - method: Marshal#dump
7
- require_name: ruby
8
- label: serialize