appmap 0.28.0 → 0.28.1
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/appmap/algorithm/stats.rb +2 -1
- data/lib/appmap/class_map.rb +1 -1
- data/lib/appmap/event.rb +6 -6
- data/lib/appmap/hook.rb +22 -13
- data/lib/appmap/rails/action_handler.rb +2 -2
- data/lib/appmap/rails/sql_handler.rb +2 -2
- data/lib/appmap/trace.rb +2 -2
- data/lib/appmap/version.rb +1 -1
- data/package-lock.json +3 -3
- data/spec/abstract_controller4_base_spec.rb +1 -1
- data/spec/abstract_controller_base_spec.rb +1 -1
- data/spec/fixtures/hook/singleton_method.rb +54 -0
- data/spec/hook_spec.rb +99 -21
- data/test/cli_test.rb +2 -2
- metadata +3 -4
- data/spec/fixtures/hook/class_method.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8619a5924ba51ee48d76ebfe5c72030629c5338217b4fe659cd0a580eaa6ddb9
|
4
|
+
data.tar.gz: 0d8b1e8fcd41e0785b362350a53c95c5bc0ba5c628371b7b6216315b7ddcd85e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4da2cadb6a852b1213d1938b035ca147a939e7dc1378ef435d1e8b4d42d6f5b98e19191ecd2e1d1e48493817117123e0b9167080308dcc9ea5527bb676f436b
|
7
|
+
data.tar.gz: 04c2a36c913a3eec42dcd8aa61e789b9b91fed1e43b4bfe84729c6a7b4451fb1064c6efdba39e3818674df8f9560caa486e1d4c8170f04682938775fbb2c4d7e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# v0.28.1
|
2
|
+
* Fix the `defined_class` recorded in an appmap for an instance method included in a class
|
3
|
+
at runtime.
|
4
|
+
|
5
|
+
* Only include the `static` attribute on `call` events in an appmap. Determine its value
|
6
|
+
based on the receiver of the method call.
|
7
|
+
|
1
8
|
# v0.28.0
|
2
9
|
|
3
10
|
* Change behavior of **AppMap.record** to return a complete AppMap as a Hash.
|
@@ -74,10 +74,11 @@ module AppMap
|
|
74
74
|
|
75
75
|
class_name_func = ->(event) { event['defined_class'] }
|
76
76
|
full_name_func = lambda do |event|
|
77
|
+
call = event['event'] == 'call'
|
77
78
|
class_name = event['defined_class']
|
78
79
|
static = event['static']
|
79
80
|
function_name = event['method_id']
|
80
|
-
[ class_name, static ? '.' : '#', function_name ].join if class_name && !static.nil? && function_name
|
81
|
+
[ class_name, static ? '.' : '#', function_name ].join if call && class_name && !static.nil? && function_name
|
81
82
|
end
|
82
83
|
|
83
84
|
class_frequency = frequency_calc.call(class_name_func)
|
data/lib/appmap/class_map.rb
CHANGED
data/lib/appmap/event.rb
CHANGED
@@ -15,15 +15,13 @@ module AppMap
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
MethodEventStruct = Struct.new(:id, :event, :defined_class, :method_id, :path, :lineno, :
|
18
|
+
MethodEventStruct = Struct.new(:id, :event, :defined_class, :method_id, :path, :lineno, :thread_id)
|
19
19
|
|
20
20
|
class MethodEvent < MethodEventStruct
|
21
21
|
LIMIT = 100
|
22
22
|
|
23
23
|
class << self
|
24
24
|
def build_from_invocation(me, event_type, defined_class, method)
|
25
|
-
singleton = method.owner.singleton_class?
|
26
|
-
|
27
25
|
me.id = AppMap::Event.next_id_counter
|
28
26
|
me.event = event_type
|
29
27
|
me.defined_class = defined_class
|
@@ -32,7 +30,6 @@ module AppMap
|
|
32
30
|
path = path[Dir.pwd.length + 1..-1] if path.index(Dir.pwd) == 0
|
33
31
|
me.path = path
|
34
32
|
me.lineno = method.source_location[1]
|
35
|
-
me.static = singleton
|
36
33
|
me.thread_id = Thread.current.object_id
|
37
34
|
end
|
38
35
|
|
@@ -62,11 +59,10 @@ module AppMap
|
|
62
59
|
end
|
63
60
|
end
|
64
61
|
|
65
|
-
alias static? static
|
66
62
|
end
|
67
63
|
|
68
64
|
class MethodCall < MethodEvent
|
69
|
-
attr_accessor :parameters, :receiver
|
65
|
+
attr_accessor :parameters, :receiver, :static
|
70
66
|
|
71
67
|
class << self
|
72
68
|
def build_from_invocation(mc = MethodCall.new, defined_class, method, receiver, arguments)
|
@@ -88,6 +84,7 @@ module AppMap
|
|
88
84
|
object_id: receiver.__id__,
|
89
85
|
value: display_string(receiver)
|
90
86
|
}
|
87
|
+
mc.static = receiver.is_a?(Module)
|
91
88
|
MethodEvent.build_from_invocation(mc, :call, defined_class, method)
|
92
89
|
end
|
93
90
|
end
|
@@ -95,10 +92,13 @@ module AppMap
|
|
95
92
|
|
96
93
|
def to_h
|
97
94
|
super.tap do |h|
|
95
|
+
h[:static] = static
|
98
96
|
h[:parameters] = parameters
|
99
97
|
h[:receiver] = receiver
|
100
98
|
end
|
101
99
|
end
|
100
|
+
|
101
|
+
alias static? static
|
102
102
|
end
|
103
103
|
|
104
104
|
class MethodReturnIgnoreValue < MethodEvent
|
data/lib/appmap/hook.rb
CHANGED
@@ -106,15 +106,24 @@ module AppMap
|
|
106
106
|
# Skip methods that have no instruction sequence, as they are obviously trivial.
|
107
107
|
next unless disasm
|
108
108
|
|
109
|
-
defined_class, method_symbol =
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
109
|
+
defined_class, method_symbol = if method.owner.singleton_class?
|
110
|
+
# Singleton class names can take two forms:
|
111
|
+
# #<Class:Foo> or
|
112
|
+
# #<Class:#<Bar:0x0123ABC>>. Retrieve the name of
|
113
|
+
# the class from the string.
|
114
|
+
#
|
115
|
+
# (There really isn't a better way to do this. The
|
116
|
+
# singleton's reference to the class it was created
|
117
|
+
# from is stored in an instance variable named
|
118
|
+
# '__attached__'. It doesn't have the '@' prefix, so
|
119
|
+
# it's internal only, and not accessible from user
|
120
|
+
# code.)
|
121
|
+
class_name = /#<Class:((#<(?<cls>.*?):)|((?<cls>.*?)>))/.match(method.owner.to_s)['cls']
|
122
|
+
[ class_name, '.' ]
|
123
|
+
else
|
124
|
+
[ method.owner.name, '#' ]
|
125
|
+
end
|
126
|
+
|
118
127
|
method_display_name = "#{defined_class}#{method_symbol}#{method.name}"
|
119
128
|
# Don't try and trace the tracing method or there will be a stack overflow
|
120
129
|
# in the defined hook method.
|
@@ -146,11 +155,11 @@ module AppMap
|
|
146
155
|
end
|
147
156
|
end
|
148
157
|
end
|
149
|
-
end
|
150
|
-
|
151
|
-
instance_methods.each(&hook_method.call(cls))
|
152
|
-
class_methods.each(&hook_method.call(cls.singleton_class))
|
153
158
|
end
|
159
|
+
|
160
|
+
instance_methods.each(&hook_method.call(cls))
|
161
|
+
class_methods.each(&hook_method.call(cls.singleton_class))
|
162
|
+
end
|
154
163
|
end
|
155
164
|
end
|
156
165
|
end
|
@@ -20,7 +20,7 @@ module AppMap
|
|
20
20
|
attr_accessor :payload
|
21
21
|
|
22
22
|
def initialize(path, lineno, payload)
|
23
|
-
super AppMap::Event.next_id_counter, :call, HTTPServerRequest, :call, path, lineno,
|
23
|
+
super AppMap::Event.next_id_counter, :call, HTTPServerRequest, :call, path, lineno, Thread.current.object_id
|
24
24
|
|
25
25
|
self.payload = payload
|
26
26
|
end
|
@@ -60,7 +60,7 @@ module AppMap
|
|
60
60
|
attr_accessor :payload
|
61
61
|
|
62
62
|
def initialize(path, lineno, payload, parent_id, elapsed)
|
63
|
-
super AppMap::Event.next_id_counter, :return, HTTPServerResponse, :call, path, lineno,
|
63
|
+
super AppMap::Event.next_id_counter, :return, HTTPServerResponse, :call, path, lineno, Thread.current.object_id
|
64
64
|
|
65
65
|
self.payload = payload
|
66
66
|
self.parent_id = parent_id
|
@@ -9,7 +9,7 @@ module AppMap
|
|
9
9
|
attr_accessor :payload
|
10
10
|
|
11
11
|
def initialize(path, lineno, payload)
|
12
|
-
super AppMap::Event.next_id_counter, :call, SQLHandler, :call, path, lineno,
|
12
|
+
super AppMap::Event.next_id_counter, :call, SQLHandler, :call, path, lineno, Thread.current.object_id
|
13
13
|
|
14
14
|
self.payload = payload
|
15
15
|
end
|
@@ -30,7 +30,7 @@ module AppMap
|
|
30
30
|
|
31
31
|
class SQLReturn < AppMap::Event::MethodReturnIgnoreValue
|
32
32
|
def initialize(path, lineno, parent_id, elapsed)
|
33
|
-
super AppMap::Event.next_id_counter, :return, SQLHandler, :call, path, lineno,
|
33
|
+
super AppMap::Event.next_id_counter, :return, SQLHandler, :call, path, lineno, Thread.current.object_id
|
34
34
|
|
35
35
|
self.parent_id = parent_id
|
36
36
|
self.elapsed = elapsed
|
data/lib/appmap/trace.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module AppMap
|
4
4
|
module Trace
|
5
|
-
ScopedMethod = Struct.new(:defined_class, :method)
|
5
|
+
ScopedMethod = Struct.new(:defined_class, :method, :static)
|
6
6
|
|
7
7
|
class Tracing
|
8
8
|
def initialize
|
@@ -67,7 +67,7 @@ module AppMap
|
|
67
67
|
return unless @enabled
|
68
68
|
|
69
69
|
@events << event
|
70
|
-
@methods << Trace::ScopedMethod.new(defined_class, method) if defined_class && method
|
70
|
+
@methods << Trace::ScopedMethod.new(defined_class, method, event.static) if (defined_class && method && event.event == :call)
|
71
71
|
end
|
72
72
|
|
73
73
|
# Gets a unique list of the methods that were invoked by the program.
|
data/lib/appmap/version.rb
CHANGED
data/package-lock.json
CHANGED
@@ -551,9 +551,9 @@
|
|
551
551
|
}
|
552
552
|
},
|
553
553
|
"lodash": {
|
554
|
-
"version": "4.17.
|
555
|
-
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.
|
556
|
-
"integrity": "sha512-
|
554
|
+
"version": "4.17.19",
|
555
|
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
556
|
+
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
|
557
557
|
},
|
558
558
|
"longest": {
|
559
559
|
"version": "1.0.1",
|
@@ -57,8 +57,8 @@ describe 'AbstractControllerBase' do
|
|
57
57
|
method_id: build_user
|
58
58
|
path: app/controllers/api/users_controller.rb
|
59
59
|
lineno: 23
|
60
|
-
static: false
|
61
60
|
thread_id: .*
|
61
|
+
static: false
|
62
62
|
parameters:
|
63
63
|
- name: params
|
64
64
|
class: ActiveSupport::HashWithIndifferentAccess
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SingletonMethod
|
4
|
+
class << self
|
5
|
+
def say_default
|
6
|
+
'default'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def SingletonMethod.say_class_defined
|
11
|
+
'defined with explicit class scope'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.say_self_defined
|
15
|
+
'defined with self class scope'
|
16
|
+
end
|
17
|
+
|
18
|
+
# When called, do_include calls +include+ to bring in the module
|
19
|
+
# AddMethod. AddMethod defines a new instance method, which gets
|
20
|
+
# added to the singleton class of SingletonMethod.
|
21
|
+
def do_include
|
22
|
+
class << self
|
23
|
+
SingletonMethod.include(AddMethod)
|
24
|
+
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.new_with_instance_method
|
29
|
+
SingletonMethod.new.tap do |m|
|
30
|
+
def m.say_instance_defined
|
31
|
+
'defined for an instance'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
'Singleton Method fixture'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module AddMethod
|
42
|
+
def self.included(base)
|
43
|
+
base.module_eval do
|
44
|
+
define_method "added_method" do
|
45
|
+
_added_method
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def _added_method
|
51
|
+
'defined by including a module'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
data/spec/hook_spec.rb
CHANGED
@@ -5,6 +5,16 @@ require 'appmap/hook'
|
|
5
5
|
require 'appmap/event'
|
6
6
|
require 'diffy'
|
7
7
|
|
8
|
+
# Show nulls as the literal +null+, rather than just leaving the field
|
9
|
+
# empty. This make some of the expected YAML below easier to
|
10
|
+
# understand.
|
11
|
+
module ShowYamlNulls
|
12
|
+
def visit_NilClass(o)
|
13
|
+
@emitter.scalar('null', nil, 'tag:yaml.org,2002:null', true, false, Psych::Nodes::Scalar::ANY)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
Psych::Visitors::YAMLTree.prepend(ShowYamlNulls)
|
17
|
+
|
8
18
|
describe 'AppMap class Hooking' do
|
9
19
|
def collect_events(tracer)
|
10
20
|
[].tap do |events|
|
@@ -30,26 +40,28 @@ describe 'AppMap class Hooking' do
|
|
30
40
|
end.to_yaml
|
31
41
|
end
|
32
42
|
|
33
|
-
def invoke_test_file(file, &block)
|
43
|
+
def invoke_test_file(file, setup: nil, &block)
|
34
44
|
AppMap.configuration = nil
|
35
45
|
package = AppMap::Hook::Package.new(file, [])
|
36
46
|
config = AppMap::Hook::Config.new('hook_spec', [ package ])
|
37
47
|
AppMap.configuration = config
|
38
48
|
AppMap::Hook.hook(config)
|
49
|
+
|
50
|
+
setup_result = setup.call if setup
|
39
51
|
|
40
52
|
tracer = AppMap.tracing.trace
|
41
53
|
AppMap::Event.reset_id_counter
|
42
54
|
begin
|
43
55
|
load file
|
44
|
-
yield
|
56
|
+
yield setup_result
|
45
57
|
ensure
|
46
58
|
AppMap.tracing.delete(tracer)
|
47
59
|
end
|
48
60
|
[ config, tracer ]
|
49
61
|
end
|
50
62
|
|
51
|
-
def test_hook_behavior(file, events_yaml, &block)
|
52
|
-
config, tracer = invoke_test_file(file, &block)
|
63
|
+
def test_hook_behavior(file, events_yaml, setup: nil, &block)
|
64
|
+
config, tracer = invoke_test_file(file, setup: setup, &block)
|
53
65
|
|
54
66
|
events = collect_events(tracer)
|
55
67
|
expect(Diffy::Diff.new(events, events_yaml).to_s).to eq('')
|
@@ -208,7 +220,7 @@ describe 'AppMap class Hooking' do
|
|
208
220
|
:parameters:
|
209
221
|
- :name: :kw
|
210
222
|
:class: NilClass
|
211
|
-
:value:
|
223
|
+
:value: null
|
212
224
|
:kind: :key
|
213
225
|
:receiver:
|
214
226
|
:class: InstanceMethod
|
@@ -238,7 +250,7 @@ describe 'AppMap class Hooking' do
|
|
238
250
|
:parameters:
|
239
251
|
- :name: :block
|
240
252
|
:class: NilClass
|
241
|
-
:value:
|
253
|
+
:value: null
|
242
254
|
:kind: :block
|
243
255
|
:receiver:
|
244
256
|
:class: InstanceMethod
|
@@ -260,15 +272,15 @@ describe 'AppMap class Hooking' do
|
|
260
272
|
---
|
261
273
|
- :id: 1
|
262
274
|
:event: :call
|
263
|
-
:defined_class:
|
275
|
+
:defined_class: SingletonMethod
|
264
276
|
:method_id: say_default
|
265
|
-
:path: spec/fixtures/hook/
|
277
|
+
:path: spec/fixtures/hook/singleton_method.rb
|
266
278
|
:lineno: 5
|
267
279
|
:static: true
|
268
280
|
:parameters: []
|
269
281
|
:receiver:
|
270
282
|
:class: Class
|
271
|
-
:value:
|
283
|
+
:value: SingletonMethod
|
272
284
|
- :id: 2
|
273
285
|
:event: :return
|
274
286
|
:parent_id: 1
|
@@ -276,8 +288,8 @@ describe 'AppMap class Hooking' do
|
|
276
288
|
:class: String
|
277
289
|
:value: default
|
278
290
|
YAML
|
279
|
-
test_hook_behavior 'spec/fixtures/hook/
|
280
|
-
expect(
|
291
|
+
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml do
|
292
|
+
expect(SingletonMethod.say_default).to eq('default')
|
281
293
|
end
|
282
294
|
end
|
283
295
|
|
@@ -286,15 +298,15 @@ describe 'AppMap class Hooking' do
|
|
286
298
|
---
|
287
299
|
- :id: 1
|
288
300
|
:event: :call
|
289
|
-
:defined_class:
|
301
|
+
:defined_class: SingletonMethod
|
290
302
|
:method_id: say_class_defined
|
291
|
-
:path: spec/fixtures/hook/
|
303
|
+
:path: spec/fixtures/hook/singleton_method.rb
|
292
304
|
:lineno: 10
|
293
305
|
:static: true
|
294
306
|
:parameters: []
|
295
307
|
:receiver:
|
296
308
|
:class: Class
|
297
|
-
:value:
|
309
|
+
:value: SingletonMethod
|
298
310
|
- :id: 2
|
299
311
|
:event: :return
|
300
312
|
:parent_id: 1
|
@@ -302,8 +314,8 @@ describe 'AppMap class Hooking' do
|
|
302
314
|
:class: String
|
303
315
|
:value: defined with explicit class scope
|
304
316
|
YAML
|
305
|
-
test_hook_behavior 'spec/fixtures/hook/
|
306
|
-
expect(
|
317
|
+
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml do
|
318
|
+
expect(SingletonMethod.say_class_defined).to eq('defined with explicit class scope')
|
307
319
|
end
|
308
320
|
end
|
309
321
|
|
@@ -312,15 +324,15 @@ describe 'AppMap class Hooking' do
|
|
312
324
|
---
|
313
325
|
- :id: 1
|
314
326
|
:event: :call
|
315
|
-
:defined_class:
|
327
|
+
:defined_class: SingletonMethod
|
316
328
|
:method_id: say_self_defined
|
317
|
-
:path: spec/fixtures/hook/
|
329
|
+
:path: spec/fixtures/hook/singleton_method.rb
|
318
330
|
:lineno: 14
|
319
331
|
:static: true
|
320
332
|
:parameters: []
|
321
333
|
:receiver:
|
322
334
|
:class: Class
|
323
|
-
:value:
|
335
|
+
:value: SingletonMethod
|
324
336
|
- :id: 2
|
325
337
|
:event: :return
|
326
338
|
:parent_id: 1
|
@@ -328,11 +340,77 @@ describe 'AppMap class Hooking' do
|
|
328
340
|
:class: String
|
329
341
|
:value: defined with self class scope
|
330
342
|
YAML
|
331
|
-
test_hook_behavior 'spec/fixtures/hook/
|
332
|
-
expect(
|
343
|
+
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml do
|
344
|
+
expect(SingletonMethod.say_self_defined).to eq('defined with self class scope')
|
333
345
|
end
|
334
346
|
end
|
335
347
|
|
348
|
+
|
349
|
+
it 'hooks an included method' do
|
350
|
+
events_yaml = <<~YAML
|
351
|
+
---
|
352
|
+
- :id: 1
|
353
|
+
:event: :call
|
354
|
+
:defined_class: SingletonMethod
|
355
|
+
:method_id: added_method
|
356
|
+
:path: spec/fixtures/hook/singleton_method.rb
|
357
|
+
:lineno: 44
|
358
|
+
:static: false
|
359
|
+
:parameters: []
|
360
|
+
:receiver:
|
361
|
+
:class: SingletonMethod
|
362
|
+
:value: Singleton Method fixture
|
363
|
+
- :id: 2
|
364
|
+
:event: :call
|
365
|
+
:defined_class: AddMethod
|
366
|
+
:method_id: _added_method
|
367
|
+
:path: spec/fixtures/hook/singleton_method.rb
|
368
|
+
:lineno: 50
|
369
|
+
:static: false
|
370
|
+
:parameters: []
|
371
|
+
:receiver:
|
372
|
+
:class: SingletonMethod
|
373
|
+
:value: Singleton Method fixture
|
374
|
+
- :id: 3
|
375
|
+
:event: :return
|
376
|
+
:parent_id: 2
|
377
|
+
:return_value:
|
378
|
+
:class: String
|
379
|
+
:value: defined by including a module
|
380
|
+
- :id: 4
|
381
|
+
:event: :return
|
382
|
+
:parent_id: 1
|
383
|
+
:return_value:
|
384
|
+
:class: String
|
385
|
+
:value: defined by including a module
|
386
|
+
YAML
|
387
|
+
|
388
|
+
load 'spec/fixtures/hook/singleton_method.rb'
|
389
|
+
setup = -> { SingletonMethod.new.do_include }
|
390
|
+
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml, setup: setup do |s|
|
391
|
+
expect(s.added_method).to eq('defined by including a module')
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
it "doesn't hook a singleton method defined for an instance" do
|
396
|
+
# Ideally, Ruby would fire a TracePoint event when a singleton
|
397
|
+
# class gets created by defining a method on an instance. It
|
398
|
+
# currently doesn't, though, so there's no way for us to hook such
|
399
|
+
# a method.
|
400
|
+
#
|
401
|
+
# This example will fail if Ruby's behavior changes at some point
|
402
|
+
# in the future.
|
403
|
+
events_yaml = <<~YAML
|
404
|
+
--- []
|
405
|
+
YAML
|
406
|
+
|
407
|
+
load 'spec/fixtures/hook/singleton_method.rb'
|
408
|
+
setup = -> { SingletonMethod.new_with_instance_method }
|
409
|
+
test_hook_behavior 'spec/fixtures/hook/singleton_method.rb', events_yaml, setup: setup do |s|
|
410
|
+
expect(s.say_instance_defined).to eq('defined for an instance')
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
336
414
|
it 'Reports exceptions' do
|
337
415
|
events_yaml = <<~YAML
|
338
416
|
---
|
data/test/cli_test.rb
CHANGED
@@ -59,7 +59,7 @@ class CLITest < Minitest::Test
|
|
59
59
|
|
60
60
|
Method frequency:
|
61
61
|
----------------
|
62
|
-
|
62
|
+
1 Main.say_hello
|
63
63
|
OUTPUT
|
64
64
|
end
|
65
65
|
|
@@ -85,7 +85,7 @@ class CLITest < Minitest::Test
|
|
85
85
|
"method_frequency": [
|
86
86
|
{
|
87
87
|
"name": "Main.say_hello",
|
88
|
-
"count":
|
88
|
+
"count": 1
|
89
89
|
}
|
90
90
|
]
|
91
91
|
}
|
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.28.
|
4
|
+
version: 0.28.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -304,10 +304,10 @@ files:
|
|
304
304
|
- spec/abstract_controller_base_spec.rb
|
305
305
|
- spec/config_spec.rb
|
306
306
|
- spec/fixtures/hook/attr_accessor.rb
|
307
|
-
- spec/fixtures/hook/class_method.rb
|
308
307
|
- spec/fixtures/hook/constructor.rb
|
309
308
|
- spec/fixtures/hook/exception_method.rb
|
310
309
|
- spec/fixtures/hook/instance_method.rb
|
310
|
+
- spec/fixtures/hook/singleton_method.rb
|
311
311
|
- spec/fixtures/rack_users_app/.dockerignore
|
312
312
|
- spec/fixtures/rack_users_app/.gitignore
|
313
313
|
- spec/fixtures/rack_users_app/Dockerfile
|
@@ -471,7 +471,6 @@ files:
|
|
471
471
|
- test/fixtures/cucumber4_recorder/features/support/hooks.rb
|
472
472
|
- test/fixtures/cucumber4_recorder/features/support/steps.rb
|
473
473
|
- test/fixtures/cucumber4_recorder/lib/hello.rb
|
474
|
-
- test/fixtures/cucumber_recorder/.bundle/config
|
475
474
|
- test/fixtures/cucumber_recorder/Gemfile
|
476
475
|
- test/fixtures/cucumber_recorder/appmap.yml
|
477
476
|
- test/fixtures/cucumber_recorder/features/say_hello.feature
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class ClassMethod
|
4
|
-
class << self
|
5
|
-
def say_default
|
6
|
-
'default'
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def ClassMethod.say_class_defined
|
11
|
-
'defined with explicit class scope'
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.say_self_defined
|
15
|
-
'defined with self class scope'
|
16
|
-
end
|
17
|
-
end
|