appmap 0.37.2 → 0.38.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +3 -0
- data/lib/appmap/config.rb +22 -10
- data/lib/appmap/hook/method.rb +18 -12
- data/lib/appmap/trace.rb +18 -7
- data/lib/appmap/version.rb +1 -1
- data/spec/abstract_controller_base_spec.rb +64 -33
- data/spec/fixtures/rails5_users_app/Gemfile +1 -1
- data/spec/fixtures/rails5_users_app/appmap.yml +1 -0
- data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_api_spec.rb +1 -1
- data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_spec.rb +16 -0
- data/spec/fixtures/rails6_users_app/Gemfile +1 -1
- data/spec/fixtures/rails6_users_app/appmap.yml +2 -0
- data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_api_spec.rb +1 -1
- data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_spec.rb +16 -0
- data/spec/hook_spec.rb +29 -7
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0255347aa61c6f39bfec0f43a78b3cc3060bd20e4f80f1e39e0ff3714a52dff3
|
4
|
+
data.tar.gz: 822bc2fe118426d6d9c9437c85ead8e603a446cabd6bd49d0053c2b1cfaf3789
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 031534a5eb015fa99d6ad161665b131677cadbe41ed1bce20357cb1ded7ba19e5f0bcbe37cfef0c8ad35cc2904fe83e4cc9d2b12d04260b970d24cc9aea64ba3
|
7
|
+
data.tar.gz: e7996262f4da21936567c1238df624220987ed04bf5aebd9a525da4d3f181ca752c1060056a5bb41b52c9cdb29e958cf7335973ac7076113278c7e8583755477
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -93,6 +93,9 @@ Each entry in the `packages` list is a YAML object which has the following keys:
|
|
93
93
|
* **gem** As an alternative to specifying the path, specify the name of a dependency gem. When using `gem`, don't specify `path`.
|
94
94
|
* **exclude** A list of files and directories which will be ignored. By default, all modules, classes and public
|
95
95
|
functions are inspected.
|
96
|
+
* **shallow** When set to `true`, only the first function call entry into a package will be recorded. Subsequent function calls within
|
97
|
+
the same package are not recorded unless code execution leaves the package and re-enters it. Default: `true` when using `gem`,
|
98
|
+
`false` when using `path`.
|
96
99
|
|
97
100
|
# Running
|
98
101
|
|
data/lib/appmap/config.rb
CHANGED
@@ -2,15 +2,22 @@
|
|
2
2
|
|
3
3
|
module AppMap
|
4
4
|
class Config
|
5
|
-
Package = Struct.new(:path, :gem, :package_name, :exclude, :labels) do
|
5
|
+
Package = Struct.new(:path, :gem, :package_name, :exclude, :labels, :shallow) do
|
6
|
+
# Indicates that only the entry points to a package will be recorded.
|
7
|
+
# Once the code has entered a package, subsequent calls within the package will not be
|
8
|
+
# recorded unless the code leaves the package and re-enters it.
|
9
|
+
def shallow?
|
10
|
+
shallow
|
11
|
+
end
|
12
|
+
|
6
13
|
class << self
|
7
|
-
def build_from_path(path, package_name: nil, exclude: [], labels: [])
|
8
|
-
Package.new(path, nil, package_name, exclude, labels)
|
14
|
+
def build_from_path(path, shallow: false, package_name: nil, exclude: [], labels: [])
|
15
|
+
Package.new(path, nil, package_name, exclude, labels, shallow)
|
9
16
|
end
|
10
17
|
|
11
|
-
def build_from_gem(gem, package_name: nil, exclude: [], labels: [])
|
18
|
+
def build_from_gem(gem, shallow: true, package_name: nil, exclude: [], labels: [])
|
12
19
|
gem_paths(gem).map do |gem_path|
|
13
|
-
Package.new(gem_path, gem, package_name, exclude, labels)
|
20
|
+
Package.new(gem_path, gem, package_name, exclude, labels, shallow)
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
@@ -36,7 +43,8 @@ module AppMap
|
|
36
43
|
package_name: package_name,
|
37
44
|
gem: gem,
|
38
45
|
exclude: exclude.blank? ? nil : exclude,
|
39
|
-
labels: labels.blank? ? nil : labels
|
46
|
+
labels: labels.blank? ? nil : labels,
|
47
|
+
shallow: shallow
|
40
48
|
}.compact
|
41
49
|
end
|
42
50
|
end
|
@@ -49,7 +57,8 @@ module AppMap
|
|
49
57
|
# Methods that should always be hooked, with their containing
|
50
58
|
# package and labels that should be applied to them.
|
51
59
|
HOOKED_METHODS = {
|
52
|
-
'ActiveSupport::SecurityUtils' => Hook.new(:secure_compare, Package.build_from_path('active_support', package_name: 'active_support', labels: %w[security crypto]))
|
60
|
+
'ActiveSupport::SecurityUtils' => Hook.new(:secure_compare, Package.build_from_path('active_support', package_name: 'active_support', labels: %w[security crypto])),
|
61
|
+
'ActionView::Renderer' => Hook.new(:render, Package.build_from_path('action_view', package_name: 'action_view', labels: %w[view]))
|
53
62
|
}.freeze
|
54
63
|
|
55
64
|
BUILTIN_METHODS = {
|
@@ -66,7 +75,7 @@ module AppMap
|
|
66
75
|
'Marshal' => Hook.new(%i[dump load], Package.build_from_path('marshal', labels: %w[serialization marshal])),
|
67
76
|
'Psych' => Hook.new(%i[dump dump_stream load load_stream parse parse_stream], Package.build_from_path('yaml', package_name: 'psych', labels: %w[serialization yaml])),
|
68
77
|
'JSON::Ext::Parser' => Hook.new(:parse, Package.build_from_path('json', package_name: 'json', labels: %w[serialization json])),
|
69
|
-
'JSON::Ext::Generator::State' => Hook.new(:generate, Package.build_from_path('json', package_name: 'json', labels: %w[serialization json]))
|
78
|
+
'JSON::Ext::Generator::State' => Hook.new(:generate, Package.build_from_path('json', package_name: 'json', labels: %w[serialization json])),
|
70
79
|
}.freeze
|
71
80
|
|
72
81
|
attr_reader :name, :packages
|
@@ -91,9 +100,12 @@ module AppMap
|
|
91
100
|
raise 'AppMap package configuration should specify gem or path, not both' if gem && path
|
92
101
|
|
93
102
|
if gem
|
94
|
-
|
103
|
+
shallow = package['shallow']
|
104
|
+
# shallow is true by default for gems
|
105
|
+
shallow = true if shallow.nil?
|
106
|
+
Package.build_from_gem(gem, exclude: package['exclude'] || [], shallow: shallow)
|
95
107
|
else
|
96
|
-
[ Package.build_from_path(path, exclude: package['exclude'] || []) ]
|
108
|
+
[ Package.build_from_path(path, exclude: package['exclude'] || [], shallow: package['shallow']) ]
|
97
109
|
end
|
98
110
|
end.flatten
|
99
111
|
Config.new config_data['name'], packages
|
data/lib/appmap/hook/method.rb
CHANGED
@@ -39,6 +39,7 @@ module AppMap
|
|
39
39
|
end
|
40
40
|
|
41
41
|
defined_class = @defined_class
|
42
|
+
hook_package = self.hook_package
|
42
43
|
hook_method = self.hook_method
|
43
44
|
before_hook = self.method(:before_hook)
|
44
45
|
after_hook = self.method(:after_hook)
|
@@ -48,29 +49,34 @@ module AppMap
|
|
48
49
|
hook_class.instance_eval do
|
49
50
|
hook_method_def = Proc.new do |*args, &block|
|
50
51
|
instance_method = hook_method.bind(self).to_proc
|
52
|
+
call_instance_method = -> { instance_method.call(*args, &block) }
|
51
53
|
|
52
54
|
# We may not have gotten the class for the method during
|
53
55
|
# initialization (e.g. for a singleton method on an embedded
|
54
56
|
# struct), so make sure we have it now.
|
55
|
-
defined_class,
|
57
|
+
defined_class, = Hook.qualify_method_name(hook_method) unless defined_class
|
56
58
|
|
57
|
-
|
58
|
-
|
59
|
-
|
59
|
+
reentrant = Thread.current[HOOK_DISABLE_KEY]
|
60
|
+
disabled_by_shallow_flag = \
|
61
|
+
-> { hook_package&.shallow? && AppMap.tracing.last_package_for_current_thread == hook_package }
|
60
62
|
|
61
|
-
|
62
|
-
|
63
|
+
enabled = true if AppMap.tracing.enabled? && !reentrant && !disabled_by_shallow_flag.call
|
64
|
+
|
65
|
+
return call_instance_method.call unless enabled
|
66
|
+
|
67
|
+
call_event, start_time = with_disabled_hook.call do
|
68
|
+
before_hook.call(self, defined_class, args)
|
63
69
|
end
|
64
70
|
return_value = nil
|
65
71
|
exception = nil
|
66
72
|
begin
|
67
|
-
return_value =
|
73
|
+
return_value = call_instance_method.call
|
68
74
|
rescue
|
69
75
|
exception = $ERROR_INFO
|
70
76
|
raise
|
71
77
|
ensure
|
72
|
-
with_disabled_hook.
|
73
|
-
after_hook.(self, call_event, start_time, return_value, exception)
|
78
|
+
with_disabled_hook.call do
|
79
|
+
after_hook.call(self, call_event, start_time, return_value, exception)
|
74
80
|
end
|
75
81
|
end
|
76
82
|
end
|
@@ -87,7 +93,7 @@ module AppMap
|
|
87
93
|
[ call_event, TIME_NOW.call ]
|
88
94
|
end
|
89
95
|
|
90
|
-
def after_hook(
|
96
|
+
def after_hook(_receiver, call_event, start_time, return_value, exception)
|
91
97
|
require 'appmap/event'
|
92
98
|
elapsed = TIME_NOW.call - start_time
|
93
99
|
return_event = \
|
@@ -95,12 +101,12 @@ module AppMap
|
|
95
101
|
AppMap.tracing.record_event return_event
|
96
102
|
end
|
97
103
|
|
98
|
-
def with_disabled_hook(&
|
104
|
+
def with_disabled_hook(&function)
|
99
105
|
# Don't record functions, such as to_s and inspect, that might be called
|
100
106
|
# by the fn. Otherwise there can be a stack overflow.
|
101
107
|
Thread.current[HOOK_DISABLE_KEY] = true
|
102
108
|
begin
|
103
|
-
|
109
|
+
function.call
|
104
110
|
ensure
|
105
111
|
Thread.current[HOOK_DISABLE_KEY] = false
|
106
112
|
end
|
data/lib/appmap/trace.rb
CHANGED
@@ -15,34 +15,38 @@ module AppMap
|
|
15
15
|
|
16
16
|
class Tracing
|
17
17
|
def initialize
|
18
|
-
@
|
18
|
+
@tracers = []
|
19
19
|
end
|
20
20
|
|
21
21
|
def empty?
|
22
|
-
@
|
22
|
+
@tracers.empty?
|
23
23
|
end
|
24
24
|
|
25
25
|
def trace(enable: true)
|
26
26
|
Tracer.new.tap do |tracer|
|
27
|
-
@
|
27
|
+
@tracers << tracer
|
28
28
|
tracer.enable if enable
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def enabled?
|
33
|
-
@
|
33
|
+
@tracers.any?(&:enabled?)
|
34
|
+
end
|
35
|
+
|
36
|
+
def last_package_for_current_thread
|
37
|
+
@tracers.first&.last_package_for_current_thread
|
34
38
|
end
|
35
39
|
|
36
40
|
def record_event(event, package: nil, defined_class: nil, method: nil)
|
37
|
-
@
|
41
|
+
@tracers.each do |tracer|
|
38
42
|
tracer.record_event(event, package: package, defined_class: defined_class, method: method)
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
46
|
def delete(tracer)
|
43
|
-
return unless @
|
47
|
+
return unless @tracers.member?(tracer)
|
44
48
|
|
45
|
-
@
|
49
|
+
@tracers.delete(tracer)
|
46
50
|
tracer.disable
|
47
51
|
end
|
48
52
|
end
|
@@ -52,6 +56,7 @@ module AppMap
|
|
52
56
|
# Records the events which happen in a program.
|
53
57
|
def initialize
|
54
58
|
@events = []
|
59
|
+
@last_package_for_thread = {}
|
55
60
|
@methods = Set.new
|
56
61
|
@enabled = false
|
57
62
|
end
|
@@ -75,11 +80,17 @@ module AppMap
|
|
75
80
|
def record_event(event, package: nil, defined_class: nil, method: nil)
|
76
81
|
return unless @enabled
|
77
82
|
|
83
|
+
@last_package_for_thread[Thread.current.object_id] = package if package
|
78
84
|
@events << event
|
79
85
|
@methods << Trace::ScopedMethod.new(package, defined_class, method, event.static) \
|
80
86
|
if package && defined_class && method && (event.event == :call)
|
81
87
|
end
|
82
88
|
|
89
|
+
# Gets the last package which was observed on the current thread.
|
90
|
+
def last_package_for_current_thread
|
91
|
+
@last_package_for_thread[Thread.current.object_id]
|
92
|
+
end
|
93
|
+
|
83
94
|
# Gets a unique list of the methods that were invoked by the program.
|
84
95
|
def event_methods
|
85
96
|
@methods.to_a
|
data/lib/appmap/version.rb
CHANGED
@@ -3,60 +3,65 @@ require 'rails_spec_helper'
|
|
3
3
|
describe 'AbstractControllerBase' do
|
4
4
|
shared_examples 'rails version' do |rails_major_version|
|
5
5
|
include_context 'Rails app pg database', "spec/fixtures/rails#{rails_major_version}_users_app" do
|
6
|
-
|
7
|
-
|
8
|
-
FileUtils.mkdir_p tmpdir
|
9
|
-
cmd = "docker-compose run --rm -e APPMAP=true -v #{File.absolute_path tmpdir}:/app/tmp app ./bin/rspec spec/controllers/users_controller_api_spec.rb:8"
|
6
|
+
def run_spec(spec_name)
|
7
|
+
cmd = "docker-compose run --rm -e APPMAP=true -v #{File.absolute_path tmpdir}:/app/tmp app ./bin/rspec #{spec_name}"
|
10
8
|
run_cmd cmd, chdir: fixture_dir
|
9
|
+
end
|
11
10
|
|
12
|
-
|
11
|
+
before do
|
12
|
+
FileUtils.rm_rf tmpdir
|
13
|
+
FileUtils.mkdir_p tmpdir
|
14
|
+
run_spec spec_name
|
13
15
|
end
|
14
16
|
|
15
17
|
let(:tmpdir) { 'tmp/spec/AbstractControllerBase' }
|
16
|
-
let(:appmap_json) { File.join(tmpdir, 'appmap/rspec/Api_UsersController_POST_api_users_with_required_parameters_creates_a_user.appmap.json') }
|
17
18
|
|
18
19
|
describe 'testing with rspec' do
|
19
|
-
|
20
|
-
|
21
|
-
end
|
20
|
+
let(:spec_name) { 'spec/controllers/users_controller_api_spec.rb:8' }
|
21
|
+
let(:appmap_json_file) { File.join(tmpdir, 'appmap/rspec/Api_UsersController_POST_api_users_with_required_parameters_creates_a_user.appmap.json') }
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
describe 'creating a user' do
|
24
|
+
it 'inventory file is printed' do
|
25
|
+
expect(File).to exist(File.join(tmpdir, 'appmap/rspec/Inventory.appmap.json'))
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
+
it 'message fields are recorded in the appmap' do
|
29
|
+
expect(File).to exist(appmap_json_file)
|
30
|
+
appmap = JSON.parse(File.read(appmap_json_file)).to_yaml
|
31
|
+
|
32
|
+
expect(appmap).to include(<<-MESSAGE.strip)
|
28
33
|
message:
|
29
34
|
- name: login
|
30
35
|
class: String
|
31
36
|
value: alice
|
32
37
|
object_id:
|
33
|
-
|
38
|
+
MESSAGE
|
34
39
|
|
35
|
-
|
40
|
+
expect(appmap).to include(<<-MESSAGE.strip)
|
36
41
|
- name: password
|
37
42
|
class: String
|
38
43
|
value: "[FILTERED]"
|
39
44
|
object_id:
|
40
|
-
|
45
|
+
MESSAGE
|
41
46
|
|
42
|
-
|
47
|
+
expect(appmap).to include(<<-SERVER_REQUEST.strip)
|
43
48
|
http_server_request:
|
44
49
|
request_method: POST
|
45
50
|
path_info: "/api/users"
|
46
|
-
|
51
|
+
SERVER_REQUEST
|
47
52
|
|
48
|
-
|
53
|
+
expect(appmap).to include(<<-SERVER_RESPONSE.strip)
|
49
54
|
http_server_response:
|
50
55
|
status: 201
|
51
56
|
mime_type: application/json; charset=utf-8
|
52
|
-
|
53
|
-
|
57
|
+
SERVER_RESPONSE
|
58
|
+
end
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
it 'properly captures method parameters in the appmap' do
|
61
|
+
expect(File).to exist(appmap_json_file)
|
62
|
+
appmap = JSON.parse(File.read(appmap_json_file)).to_yaml
|
58
63
|
|
59
|
-
|
64
|
+
expect(appmap).to match(<<-CREATE_CALL.strip)
|
60
65
|
event: call
|
61
66
|
thread_id: .*
|
62
67
|
defined_class: Api::UsersController
|
@@ -71,19 +76,45 @@ describe 'AbstractControllerBase' do
|
|
71
76
|
value: '{"login"=>"alice"}'
|
72
77
|
kind: req
|
73
78
|
receiver:
|
74
|
-
|
79
|
+
CREATE_CALL
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns a minimal event' do
|
83
|
+
expect(File).to exist(appmap_json_file)
|
84
|
+
appmap = JSON.parse(File.read(appmap_json_file))
|
85
|
+
event = appmap['events'].find { |event| event['event'] == 'return' && event['return_value'] }
|
86
|
+
expect(event.keys).to eq(%w[id event thread_id parent_id elapsed return_value])
|
87
|
+
end
|
75
88
|
end
|
76
89
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
90
|
+
describe 'listing users' do
|
91
|
+
let(:spec_name) { 'spec/controllers/users_controller_spec.rb:11' }
|
92
|
+
let(:appmap_json_file) { File.join(tmpdir, 'appmap/rspec/UsersController_GET_users_lists_the_users.appmap.json') }
|
93
|
+
it 'records and labels view rendering' do
|
94
|
+
expect(File).to exist(appmap_json_file)
|
95
|
+
appmap = JSON.parse(File.read(appmap_json_file)).to_yaml
|
96
|
+
|
97
|
+
expect(appmap).to match(<<-VIEW_CALL.strip)
|
98
|
+
event: call
|
99
|
+
thread_id: .*
|
100
|
+
defined_class: ActionView::Renderer
|
101
|
+
method_id: render
|
102
|
+
path: .*
|
103
|
+
lineno: .*
|
104
|
+
static: false
|
105
|
+
VIEW_CALL
|
106
|
+
|
107
|
+
expect(appmap).to match(<<-VIEW_LABEL.strip)
|
108
|
+
labels:
|
109
|
+
- view
|
110
|
+
VIEW_LABEL
|
111
|
+
end
|
82
112
|
end
|
83
113
|
end
|
84
114
|
end
|
85
115
|
end
|
86
116
|
|
87
|
-
|
88
|
-
|
117
|
+
%w[5 6].each do |version|
|
118
|
+
it_behaves_like 'rails version', version
|
119
|
+
end
|
89
120
|
end
|
@@ -21,7 +21,7 @@ RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller,
|
|
21
21
|
post :create, params: { login: 'alice' }
|
22
22
|
end
|
23
23
|
it 'lists the users' do
|
24
|
-
|
24
|
+
get :index, params: {}
|
25
25
|
users = JSON.parse(response.body)
|
26
26
|
expect(users.map { |r| r['login'] }).to include('alice')
|
27
27
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
|
4
|
+
RSpec.describe UsersController, type: :controller do
|
5
|
+
render_views
|
6
|
+
|
7
|
+
describe 'GET /users', feature: 'Show all users' do
|
8
|
+
before do
|
9
|
+
User.create login: 'alice'
|
10
|
+
end
|
11
|
+
it 'lists the users' do
|
12
|
+
get :index
|
13
|
+
expect(response).to be_ok
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -21,7 +21,7 @@ RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller,
|
|
21
21
|
post :create, params: { login: 'alice' }
|
22
22
|
end
|
23
23
|
it 'lists the users' do
|
24
|
-
|
24
|
+
get :index, params: {}
|
25
25
|
users = JSON.parse(response.body)
|
26
26
|
expect(users.map { |r| r['login'] }).to include('alice')
|
27
27
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
|
4
|
+
RSpec.describe UsersController, type: :controller do
|
5
|
+
render_views
|
6
|
+
|
7
|
+
describe 'GET /users', feature: 'Show all users' do
|
8
|
+
before do
|
9
|
+
User.create login: 'alice'
|
10
|
+
end
|
11
|
+
it 'lists the users' do
|
12
|
+
get :index
|
13
|
+
expect(response).to be_ok
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/hook_spec.rb
CHANGED
@@ -52,9 +52,9 @@ describe 'AppMap class Hooking', docker: false do
|
|
52
52
|
|
53
53
|
events = collect_events(tracer).to_yaml
|
54
54
|
|
55
|
-
expect(Diffy::Diff.new(events_yaml, events).to_s).to eq('')
|
55
|
+
expect(Diffy::Diff.new(events_yaml, events).to_s).to eq('') if events_yaml
|
56
56
|
|
57
|
-
[ config, tracer ]
|
57
|
+
[ config, tracer, events ]
|
58
58
|
end
|
59
59
|
|
60
60
|
after do
|
@@ -741,9 +741,33 @@ describe 'AppMap class Hooking', docker: false do
|
|
741
741
|
:value: 'true'
|
742
742
|
YAML
|
743
743
|
|
744
|
-
test_hook_behavior 'spec/fixtures/hook/compare.rb',
|
744
|
+
_, _, events = test_hook_behavior 'spec/fixtures/hook/compare.rb', nil do
|
745
745
|
expect(Compare.compare('string', 'string')).to be_truthy
|
746
746
|
end
|
747
|
+
secure_compare_event = YAML.load(events).find { |evt| evt[:defined_class] == 'ActiveSupport::SecurityUtils' }
|
748
|
+
secure_compare_event.delete(:lineno)
|
749
|
+
|
750
|
+
expect(Diffy::Diff.new(<<~YAML, secure_compare_event.to_yaml).to_s).to eq('')
|
751
|
+
---
|
752
|
+
:id: 2
|
753
|
+
:event: :call
|
754
|
+
:defined_class: ActiveSupport::SecurityUtils
|
755
|
+
:method_id: secure_compare
|
756
|
+
:path: lib/active_support/security_utils.rb
|
757
|
+
:static: true
|
758
|
+
:parameters:
|
759
|
+
- :name: :a
|
760
|
+
:class: String
|
761
|
+
:value: string
|
762
|
+
:kind: :req
|
763
|
+
- :name: :b
|
764
|
+
:class: String
|
765
|
+
:value: string
|
766
|
+
:kind: :req
|
767
|
+
:receiver:
|
768
|
+
:class: Module
|
769
|
+
:value: ActiveSupport::SecurityUtils
|
770
|
+
YAML
|
747
771
|
end
|
748
772
|
|
749
773
|
it 'gets labeled in the classmap' do
|
@@ -806,16 +830,14 @@ describe 'AppMap class Hooking', docker: false do
|
|
806
830
|
- crypto
|
807
831
|
YAML
|
808
832
|
|
809
|
-
|
833
|
+
_, tracer = invoke_test_file 'spec/fixtures/hook/compare.rb' do
|
810
834
|
expect(Compare.compare('string', 'string')).to be_truthy
|
811
835
|
end
|
812
836
|
cm = AppMap::Util.sanitize_paths(AppMap::ClassMap.build_from_methods(tracer.event_methods))
|
813
837
|
entry = cm[1][:children][0][:children][0][:children][0]
|
814
838
|
# Sanity check, make sure we got the right one
|
815
839
|
expect(entry[:name]).to eq('secure_compare')
|
816
|
-
|
817
|
-
entry[:location].gsub!(spec.base_dir + '/', '')
|
818
|
-
expect(Diffy::Diff.new(classmap_yaml, cm.to_yaml).to_s).to eq('')
|
840
|
+
expect(entry[:labels]).to eq(%w[security crypto])
|
819
841
|
end
|
820
842
|
end
|
821
843
|
|
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.
|
4
|
+
version: 0.38.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-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -527,6 +527,7 @@ files:
|
|
527
527
|
- spec/fixtures/rails5_users_app/log/.keep
|
528
528
|
- spec/fixtures/rails5_users_app/public/robots.txt
|
529
529
|
- spec/fixtures/rails5_users_app/spec/controllers/users_controller_api_spec.rb
|
530
|
+
- spec/fixtures/rails5_users_app/spec/controllers/users_controller_spec.rb
|
530
531
|
- spec/fixtures/rails5_users_app/spec/models/user_spec.rb
|
531
532
|
- spec/fixtures/rails5_users_app/spec/rails_helper.rb
|
532
533
|
- spec/fixtures/rails5_users_app/spec/spec_helper.rb
|
@@ -598,6 +599,7 @@ files:
|
|
598
599
|
- spec/fixtures/rails6_users_app/log/.keep
|
599
600
|
- spec/fixtures/rails6_users_app/public/robots.txt
|
600
601
|
- spec/fixtures/rails6_users_app/spec/controllers/users_controller_api_spec.rb
|
602
|
+
- spec/fixtures/rails6_users_app/spec/controllers/users_controller_spec.rb
|
601
603
|
- spec/fixtures/rails6_users_app/spec/models/user_spec.rb
|
602
604
|
- spec/fixtures/rails6_users_app/spec/rails_helper.rb
|
603
605
|
- spec/fixtures/rails6_users_app/spec/spec_helper.rb
|