appmap 0.44.0 → 0.47.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/.releaserc.yml +11 -0
- data/.travis.yml +28 -12
- data/CHANGELOG.md +42 -0
- data/README.md +39 -11
- data/README_CI.md +29 -0
- data/Rakefile +4 -2
- data/appmap.gemspec +5 -1
- data/lib/appmap/class_map.rb +7 -15
- data/lib/appmap/config.rb +203 -95
- data/lib/appmap/event.rb +29 -28
- data/lib/appmap/handler/function.rb +19 -0
- data/lib/appmap/handler/net_http.rb +107 -0
- data/lib/appmap/handler/rails/request_handler.rb +124 -0
- data/lib/appmap/handler/rails/sql_handler.rb +152 -0
- data/lib/appmap/handler/rails/template.rb +155 -0
- data/lib/appmap/hook.rb +109 -71
- data/lib/appmap/hook/method.rb +6 -8
- data/lib/appmap/railtie.rb +5 -5
- data/lib/appmap/trace.rb +47 -6
- data/lib/appmap/util.rb +41 -2
- data/lib/appmap/version.rb +2 -2
- data/package-lock.json +3 -3
- data/release.sh +17 -0
- data/spec/abstract_controller_base_spec.rb +74 -11
- data/spec/class_map_spec.rb +3 -3
- data/spec/config_spec.rb +3 -1
- data/spec/hook_spec.rb +12 -66
- data/spec/record_net_http_spec.rb +160 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/util_spec.rb +18 -1
- metadata +16 -10
- data/lib/appmap/rails/request_handler.rb +0 -140
- data/lib/appmap/rails/sql_handler.rb +0 -150
- data/patch +0 -1447
data/lib/appmap/util.rb
CHANGED
@@ -61,8 +61,16 @@ module AppMap
|
|
61
61
|
delete_object_id = ->(obj) { (obj || {}).delete(:object_id) }
|
62
62
|
delete_object_id.call(event[:receiver])
|
63
63
|
delete_object_id.call(event[:return_value])
|
64
|
-
|
65
|
-
|
64
|
+
%i[parameters exceptions message].each do |field|
|
65
|
+
(event[field] || []).each(&delete_object_id)
|
66
|
+
end
|
67
|
+
%i[http_client_request http_client_response http_server_request http_server_response].each do |field|
|
68
|
+
headers = event.dig(field, :headers)
|
69
|
+
next unless headers
|
70
|
+
|
71
|
+
headers['Date'] = '<instanceof date>' if headers['Date']
|
72
|
+
headers['Server'] = headers['Server'].match(/^(\w+)/)[0] if headers['Server']
|
73
|
+
end
|
66
74
|
|
67
75
|
case event[:event]
|
68
76
|
when :call
|
@@ -72,6 +80,37 @@ module AppMap
|
|
72
80
|
event
|
73
81
|
end
|
74
82
|
|
83
|
+
def select_headers(env)
|
84
|
+
# Rack prepends HTTP_ to all client-sent headers.
|
85
|
+
matching_headers = env
|
86
|
+
.select { |k,v| k.start_with? 'HTTP_'}
|
87
|
+
.reject { |k,v| v.blank? }
|
88
|
+
.each_with_object({}) do |kv, memo|
|
89
|
+
key = kv[0].sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-')
|
90
|
+
value = kv[1]
|
91
|
+
memo[key] = value
|
92
|
+
end
|
93
|
+
matching_headers.blank? ? nil : matching_headers
|
94
|
+
end
|
95
|
+
|
96
|
+
def normalize_path(path)
|
97
|
+
if path.index(Dir.pwd) == 0
|
98
|
+
path[Dir.pwd.length + 1..-1]
|
99
|
+
else
|
100
|
+
path
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Convert a Rails-style path from /org/:org_id(.:format)
|
105
|
+
# to Swagger-style paths like /org/{org_id}
|
106
|
+
def swaggerize_path(path)
|
107
|
+
path = path.split('(.')[0]
|
108
|
+
tokens = path.split('/')
|
109
|
+
tokens.map do |token|
|
110
|
+
token.gsub /^:(.*)/, '{\1}'
|
111
|
+
end.join('/')
|
112
|
+
end
|
113
|
+
|
75
114
|
# Atomically writes AppMap data to +filename+.
|
76
115
|
def write_appmap(filename, appmap)
|
77
116
|
require 'fileutils'
|
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.21",
|
555
|
+
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
556
|
+
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
557
557
|
},
|
558
558
|
"longest": {
|
559
559
|
"version": "1.0.1",
|
data/release.sh
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# using bash wrapper as Rake blows up in `require/extentiontask` (line 10)
|
3
|
+
|
4
|
+
RELEASE_FLAGS=""
|
5
|
+
if [ ! -z "$TRAVIS_REPO_SLUG" ]; then
|
6
|
+
RELEASE_FLAGS="-r git+https://github.com/${TRAVIS_REPO_SLUG}.git"
|
7
|
+
fi
|
8
|
+
|
9
|
+
if [ ! -z "$GEM_ALTERNATIVE_NAME" ]; then
|
10
|
+
echo "Release: GEM_ALTERNATIVE_NAME=$GEM_ALTERNATIVE_NAME"
|
11
|
+
else
|
12
|
+
echo "No GEM_ALTERNATIVE_NAME is provided, releasing gem with default name ('appmap')"
|
13
|
+
fi
|
14
|
+
|
15
|
+
set -x
|
16
|
+
exec semantic-release $RELEASE_FLAGS
|
17
|
+
|
@@ -42,7 +42,7 @@ describe 'Rails' do
|
|
42
42
|
hash_including(
|
43
43
|
'http_server_request' => hash_including(
|
44
44
|
'request_method' => 'POST',
|
45
|
-
'normalized_path_info' => '/api/users
|
45
|
+
'normalized_path_info' => '/api/users',
|
46
46
|
'path_info' => '/api/users'
|
47
47
|
),
|
48
48
|
'message' => include(
|
@@ -67,8 +67,8 @@ describe 'Rails' do
|
|
67
67
|
expect(events).to include(
|
68
68
|
hash_including(
|
69
69
|
'http_server_response' => hash_including(
|
70
|
-
'
|
71
|
-
'mime_type' => 'application/json; charset=utf-8'
|
70
|
+
'status_code' => 201,
|
71
|
+
'mime_type' => 'application/json; charset=utf-8',
|
72
72
|
)
|
73
73
|
)
|
74
74
|
)
|
@@ -144,7 +144,49 @@ describe 'Rails' do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
describe 'a UI route' do
|
147
|
-
describe 'rendering a page' do
|
147
|
+
describe 'rendering a page using a template file' do
|
148
|
+
let(:appmap_json_file) do
|
149
|
+
'UsersController_GET_users_lists_the_users.appmap.json'
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'records the template file' do
|
153
|
+
expect(events).to include hash_including(
|
154
|
+
'event' => 'call',
|
155
|
+
'defined_class' => 'app_views_users_index_html_haml',
|
156
|
+
'method_id' => 'render',
|
157
|
+
'path' => 'app/views/users/index.html.haml'
|
158
|
+
)
|
159
|
+
|
160
|
+
expect(appmap['classMap']).to include hash_including(
|
161
|
+
'name' => 'app/views',
|
162
|
+
'children' => include(hash_including(
|
163
|
+
'name' => 'app_views_users_index_html_haml',
|
164
|
+
'children' => include(hash_including(
|
165
|
+
'name' => 'render',
|
166
|
+
'type' => 'function',
|
167
|
+
'location' => 'app/views/users/index.html.haml',
|
168
|
+
'static' => true,
|
169
|
+
'labels' => [ 'mvc.template' ]
|
170
|
+
))
|
171
|
+
))
|
172
|
+
)
|
173
|
+
expect(appmap['classMap']).to include hash_including(
|
174
|
+
'name' => 'app/views',
|
175
|
+
'children' => include(hash_including(
|
176
|
+
'name' => 'app_views_layouts_application_html_haml',
|
177
|
+
'children' => include(hash_including(
|
178
|
+
'name' => 'render',
|
179
|
+
'type' => 'function',
|
180
|
+
'location' => 'app/views/layouts/application.html.haml',
|
181
|
+
'static' => true,
|
182
|
+
'labels' => [ 'mvc.template' ]
|
183
|
+
))
|
184
|
+
))
|
185
|
+
)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe 'rendering a page using a text template' do
|
148
190
|
let(:appmap_json_file) do
|
149
191
|
'UsersController_GET_users_login_shows_the_user.appmap.json'
|
150
192
|
end
|
@@ -155,25 +197,46 @@ describe 'Rails' do
|
|
155
197
|
'http_server_request' => {
|
156
198
|
'request_method' => 'GET',
|
157
199
|
'path_info' => '/users/alice',
|
158
|
-
'normalized_path_info' => '/users
|
200
|
+
'normalized_path_info' => '/users/{id}',
|
201
|
+
'headers' => {
|
202
|
+
'Host' => 'test.host',
|
203
|
+
'User-Agent' => 'Rails Testing'
|
204
|
+
}
|
159
205
|
}
|
160
206
|
)
|
161
207
|
)
|
162
208
|
end
|
163
209
|
|
210
|
+
it 'ignores the text template' do
|
211
|
+
expect(events).to_not include hash_including(
|
212
|
+
'event' => 'call',
|
213
|
+
'method_id' => 'render',
|
214
|
+
'render_template' => anything
|
215
|
+
)
|
216
|
+
|
217
|
+
expect(appmap['classMap']).to_not include hash_including(
|
218
|
+
'name' => 'views',
|
219
|
+
'children' => include(hash_including(
|
220
|
+
'name' => 'ViewTemplate',
|
221
|
+
'children' => include(hash_including(
|
222
|
+
'name' => 'render',
|
223
|
+
'type' => 'function',
|
224
|
+
'location' => 'text template'
|
225
|
+
))
|
226
|
+
))
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
164
230
|
it 'records and labels view rendering' do
|
165
231
|
expect(events).to include hash_including(
|
166
232
|
'event' => 'call',
|
167
233
|
'thread_id' => Numeric,
|
168
|
-
'defined_class' => '
|
169
|
-
'method_id' => 'render'
|
170
|
-
'path' => String,
|
171
|
-
'lineno' => Integer,
|
172
|
-
'static' => false
|
234
|
+
'defined_class' => 'inline_template',
|
235
|
+
'method_id' => 'render'
|
173
236
|
)
|
174
237
|
|
175
238
|
expect(appmap['classMap']).to include hash_including(
|
176
|
-
'name' => '
|
239
|
+
'name' => 'actionview',
|
177
240
|
'children' => include(hash_including(
|
178
241
|
'name' => 'ActionView',
|
179
242
|
'children' => include(hash_including(
|
data/spec/class_map_spec.rb
CHANGED
@@ -5,7 +5,7 @@ require 'spec_helper'
|
|
5
5
|
describe 'AppMap::ClassMap' do
|
6
6
|
describe '.build_from_methods' do
|
7
7
|
it 'includes method comment' do
|
8
|
-
map = AppMap.class_map([
|
8
|
+
map = AppMap.class_map([ruby_method((method :test_method))])
|
9
9
|
function = dig_map(map, 5)[0]
|
10
10
|
expect(function).to include(:comment)
|
11
11
|
end
|
@@ -15,8 +15,8 @@ describe 'AppMap::ClassMap' do
|
|
15
15
|
'test method body'
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
AppMap::Trace::
|
18
|
+
def ruby_method(method)
|
19
|
+
AppMap::Trace::RubyMethod.new AppMap::Config::Package.new, method.receiver.class.name, method, false
|
20
20
|
end
|
21
21
|
|
22
22
|
def dig_map(map, depth)
|
data/spec/config_spec.rb
CHANGED
@@ -34,10 +34,12 @@ describe AppMap::Config, docker: false do
|
|
34
34
|
name: 'test',
|
35
35
|
packages: [
|
36
36
|
{
|
37
|
-
path: 'path-1'
|
37
|
+
path: 'path-1',
|
38
|
+
handler_class: 'AppMap::Handler::Function'
|
38
39
|
},
|
39
40
|
{
|
40
41
|
path: 'path-2',
|
42
|
+
handler_class: 'AppMap::Handler::Function',
|
41
43
|
exclude: [ 'exclude-1' ]
|
42
44
|
}
|
43
45
|
],
|
data/spec/hook_spec.rb
CHANGED
@@ -16,14 +16,7 @@ end
|
|
16
16
|
Psych::Visitors::YAMLTree.prepend(ShowYamlNulls)
|
17
17
|
|
18
18
|
describe 'AppMap class Hooking', docker: false do
|
19
|
-
|
20
|
-
def collect_events(tracer)
|
21
|
-
[].tap do |events|
|
22
|
-
while tracer.event?
|
23
|
-
events << tracer.next_event.to_h
|
24
|
-
end
|
25
|
-
end.map(&AppMap::Util.method(:sanitize_event))
|
26
|
-
end
|
19
|
+
include_context 'collect events'
|
27
20
|
|
28
21
|
def invoke_test_file(file, setup: nil, &block)
|
29
22
|
AppMap.configuration = nil
|
@@ -67,69 +60,18 @@ describe 'AppMap class Hooking', docker: false do
|
|
67
60
|
config = AppMap::Config.new('hook_spec', [ package ], exclude: %w[ExcludeTest])
|
68
61
|
AppMap.configuration = config
|
69
62
|
|
70
|
-
expect(config.never_hook?(ExcludeTest.new.method(:instance_method))).to be_truthy
|
71
|
-
expect(config.never_hook?(ExcludeTest.method(:cls_method))).to be_truthy
|
63
|
+
expect(config.never_hook?(ExcludeTest, ExcludeTest.new.method(:instance_method))).to be_truthy
|
64
|
+
expect(config.never_hook?(ExcludeTest, ExcludeTest.method(:cls_method))).to be_truthy
|
72
65
|
end
|
73
66
|
|
74
|
-
it "
|
67
|
+
it "an instance method named 'call' will be ignored" do
|
75
68
|
events_yaml = <<~YAML
|
76
|
-
---
|
77
|
-
- :id: 1
|
78
|
-
:event: :call
|
79
|
-
:defined_class: MethodNamedCall
|
80
|
-
:method_id: call
|
81
|
-
:path: spec/fixtures/hook/method_named_call.rb
|
82
|
-
:lineno: 8
|
83
|
-
:static: false
|
84
|
-
:parameters:
|
85
|
-
- :name: :a
|
86
|
-
:class: Integer
|
87
|
-
:value: '1'
|
88
|
-
:kind: :req
|
89
|
-
- :name: :b
|
90
|
-
:class: Integer
|
91
|
-
:value: '2'
|
92
|
-
:kind: :req
|
93
|
-
- :name: :c
|
94
|
-
:class: Integer
|
95
|
-
:value: '3'
|
96
|
-
:kind: :req
|
97
|
-
- :name: :d
|
98
|
-
:class: Integer
|
99
|
-
:value: '4'
|
100
|
-
:kind: :req
|
101
|
-
- :name: :e
|
102
|
-
:class: Integer
|
103
|
-
:value: '5'
|
104
|
-
:kind: :req
|
105
|
-
:receiver:
|
106
|
-
:class: MethodNamedCall
|
107
|
-
:value: MethodNamedCall
|
108
|
-
- :id: 2
|
109
|
-
:event: :return
|
110
|
-
:parent_id: 1
|
111
|
-
:return_value:
|
112
|
-
:class: String
|
113
|
-
:value: 1 2 3 4 5
|
69
|
+
--- []
|
114
70
|
YAML
|
115
71
|
|
116
72
|
_, tracer = test_hook_behavior 'spec/fixtures/hook/method_named_call.rb', events_yaml do
|
117
73
|
expect(MethodNamedCall.new.call(1, 2, 3, 4, 5)).to eq('1 2 3 4 5')
|
118
74
|
end
|
119
|
-
class_map = AppMap.class_map(tracer.event_methods)
|
120
|
-
expect(Diffy::Diff.new(<<~CLASSMAP, YAML.dump(class_map)).to_s).to eq('')
|
121
|
-
---
|
122
|
-
- :name: spec/fixtures/hook/method_named_call.rb
|
123
|
-
:type: package
|
124
|
-
:children:
|
125
|
-
- :name: MethodNamedCall
|
126
|
-
:type: class
|
127
|
-
:children:
|
128
|
-
- :name: call
|
129
|
-
:type: function
|
130
|
-
:location: spec/fixtures/hook/method_named_call.rb:8
|
131
|
-
:static: false
|
132
|
-
CLASSMAP
|
133
75
|
end
|
134
76
|
|
135
77
|
it 'can custom hook and label a function' do
|
@@ -170,7 +112,9 @@ describe 'AppMap class Hooking', docker: false do
|
|
170
112
|
method = hook_cls.instance_method(:say_default)
|
171
113
|
|
172
114
|
require 'appmap/hook/method'
|
173
|
-
|
115
|
+
package = config.lookup_package(hook_cls, method)
|
116
|
+
expect(package).to be
|
117
|
+
hook_method = AppMap::Hook::Method.new(package, hook_cls, method)
|
174
118
|
hook_method.activate
|
175
119
|
|
176
120
|
tracer = AppMap.tracing.trace
|
@@ -255,8 +199,8 @@ describe 'AppMap class Hooking', docker: false do
|
|
255
199
|
_, tracer = invoke_test_file 'spec/fixtures/hook/instance_method.rb' do
|
256
200
|
InstanceMethod.new.say_default
|
257
201
|
end
|
258
|
-
expect(tracer.event_methods.to_a.map(&:
|
259
|
-
expect(tracer.event_methods.to_a.map(&:
|
202
|
+
expect(tracer.event_methods.to_a.map(&:class_name)).to eq([ 'InstanceMethod' ])
|
203
|
+
expect(tracer.event_methods.to_a.map(&:name)).to eq([ InstanceMethod.public_instance_method(:say_default).name ])
|
260
204
|
end
|
261
205
|
|
262
206
|
it 'builds a class map of invoked methods' do
|
@@ -868,7 +812,9 @@ describe 'AppMap class Hooking', docker: false do
|
|
868
812
|
_, _, events = test_hook_behavior 'spec/fixtures/hook/compare.rb', nil do
|
869
813
|
expect(Compare.compare('string', 'string')).to be_truthy
|
870
814
|
end
|
815
|
+
|
871
816
|
secure_compare_event = YAML.load(events).find { |evt| evt[:defined_class] == 'ActiveSupport::SecurityUtils' }
|
817
|
+
expect(secure_compare_event).to be_truthy
|
872
818
|
secure_compare_event.delete(:lineno)
|
873
819
|
secure_compare_event.delete(:path)
|
874
820
|
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'diffy'
|
3
|
+
require 'rack'
|
4
|
+
require 'rack/handler/webrick'
|
5
|
+
|
6
|
+
class HelloWorldApp
|
7
|
+
def call(env)
|
8
|
+
req = Rack::Request.new(env)
|
9
|
+
case req.path_info
|
10
|
+
when /hello/
|
11
|
+
[200, {"Content-Type" => "text/html"}, ["Hello World!"]]
|
12
|
+
when /goodbye/
|
13
|
+
[500, {"Content-Type" => "text/html"}, ["Goodbye Cruel World!"]]
|
14
|
+
else
|
15
|
+
[404, {"Content-Type" => "text/html"}, ["I'm Lost!"]]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'Net::HTTP handler' do
|
21
|
+
include_context 'collect events'
|
22
|
+
|
23
|
+
def get_hello(params: nil)
|
24
|
+
http = Net::HTTP.new('localhost', 19292)
|
25
|
+
http.get [ '/hello', params ].compact.join('?')
|
26
|
+
end
|
27
|
+
|
28
|
+
before(:all) do
|
29
|
+
@rack_thread = Thread.new do
|
30
|
+
Rack::Handler::WEBrick.run HelloWorldApp.new, Port: 19292
|
31
|
+
end
|
32
|
+
10.times do
|
33
|
+
sleep 0.1
|
34
|
+
break if get_hello.code.to_i == 200
|
35
|
+
end
|
36
|
+
raise "Web server didn't start" unless get_hello.code.to_i == 200
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:all) do
|
40
|
+
@rack_thread.kill
|
41
|
+
end
|
42
|
+
|
43
|
+
def start_recording
|
44
|
+
AppMap.configuration = configuration
|
45
|
+
AppMap::Hook.new(configuration).enable
|
46
|
+
|
47
|
+
@tracer = AppMap.tracing.trace
|
48
|
+
AppMap::Event.reset_id_counter
|
49
|
+
end
|
50
|
+
|
51
|
+
def record(&block)
|
52
|
+
start_recording
|
53
|
+
begin
|
54
|
+
yield
|
55
|
+
ensure
|
56
|
+
stop_recording
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def stop_recording
|
61
|
+
AppMap.tracing.delete(@tracer)
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with trace enabled' do
|
65
|
+
let(:configuration) { AppMap::Config.new('record_net_http_spec', []) }
|
66
|
+
|
67
|
+
after do
|
68
|
+
AppMap.configuration = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'GET request' do
|
72
|
+
it 'with a single query parameter' do
|
73
|
+
record do
|
74
|
+
get_hello(params: 'msg=hi')
|
75
|
+
end
|
76
|
+
|
77
|
+
events = collect_events(@tracer).to_yaml
|
78
|
+
expect(Diffy::Diff.new(<<~EVENTS, events).to_s).to eq('')
|
79
|
+
---
|
80
|
+
- :id: 1
|
81
|
+
:event: :call
|
82
|
+
:http_client_request:
|
83
|
+
:request_method: GET
|
84
|
+
:url: http://localhost:19292/hello
|
85
|
+
:headers:
|
86
|
+
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
87
|
+
Accept: "*/*"
|
88
|
+
User-Agent: Ruby
|
89
|
+
Connection: close
|
90
|
+
:message:
|
91
|
+
- :name: msg
|
92
|
+
:class: String
|
93
|
+
:value: hi
|
94
|
+
- :id: 2
|
95
|
+
:event: :return
|
96
|
+
:parent_id: 1
|
97
|
+
:http_client_response:
|
98
|
+
:status_code: 200
|
99
|
+
:headers:
|
100
|
+
Content-Type: text/html
|
101
|
+
Server: WEBrick
|
102
|
+
Date: "<instanceof date>"
|
103
|
+
Content-Length: '12'
|
104
|
+
Connection: close
|
105
|
+
EVENTS
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'with a multi-valued query parameter' do
|
109
|
+
record do
|
110
|
+
get_hello(params: 'ary[]=1&ary[]=2')
|
111
|
+
end
|
112
|
+
|
113
|
+
event = collect_events(@tracer).first.to_yaml
|
114
|
+
expect(Diffy::Diff.new(<<~EVENT, event).to_s).to eq('')
|
115
|
+
---
|
116
|
+
:id: 1
|
117
|
+
:event: :call
|
118
|
+
:http_client_request:
|
119
|
+
:request_method: GET
|
120
|
+
:url: http://localhost:19292/hello
|
121
|
+
:headers:
|
122
|
+
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
123
|
+
Accept: "*/*"
|
124
|
+
User-Agent: Ruby
|
125
|
+
Connection: close
|
126
|
+
:message:
|
127
|
+
- :name: ary
|
128
|
+
:class: Array
|
129
|
+
:value: '["1", "2"]'
|
130
|
+
EVENT
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'with a URL encoded query parameter' do
|
134
|
+
msg = 'foo/bar?baz'
|
135
|
+
record do
|
136
|
+
get_hello(params: "msg=#{CGI.escape msg}")
|
137
|
+
end
|
138
|
+
|
139
|
+
event = collect_events(@tracer).first.to_yaml
|
140
|
+
expect(Diffy::Diff.new(<<~EVENT, event).to_s).to eq('')
|
141
|
+
---
|
142
|
+
:id: 1
|
143
|
+
:event: :call
|
144
|
+
:http_client_request:
|
145
|
+
:request_method: GET
|
146
|
+
:url: http://localhost:19292/hello
|
147
|
+
:headers:
|
148
|
+
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
149
|
+
Accept: "*/*"
|
150
|
+
User-Agent: Ruby
|
151
|
+
Connection: close
|
152
|
+
:message:
|
153
|
+
- :name: msg
|
154
|
+
:class: String
|
155
|
+
:value: #{msg}
|
156
|
+
EVENT
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|