appmap 0.41.2 → 0.45.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 +4 -4
- data/.releaserc.yml +11 -0
- data/.travis.yml +23 -2
- data/CHANGELOG.md +40 -0
- data/README.md +36 -6
- data/README_CI.md +29 -0
- data/Rakefile +4 -2
- data/appmap.gemspec +5 -3
- data/lib/appmap.rb +4 -2
- data/lib/appmap/class_map.rb +7 -10
- data/lib/appmap/config.rb +98 -28
- data/lib/appmap/cucumber.rb +1 -1
- data/lib/appmap/event.rb +18 -0
- data/lib/appmap/handler/function.rb +19 -0
- data/lib/appmap/handler/net_http.rb +107 -0
- data/lib/appmap/hook.rb +42 -22
- data/lib/appmap/hook/method.rb +5 -7
- data/lib/appmap/minitest.rb +35 -30
- data/lib/appmap/rails/request_handler.rb +30 -17
- data/lib/appmap/record.rb +1 -1
- data/lib/appmap/rspec.rb +32 -96
- data/lib/appmap/trace.rb +2 -1
- data/lib/appmap/util.rb +39 -2
- data/lib/appmap/version.rb +2 -2
- data/release.sh +17 -0
- data/spec/abstract_controller_base_spec.rb +76 -29
- data/spec/class_map_spec.rb +3 -11
- data/spec/config_spec.rb +33 -1
- data/spec/fixtures/hook/custom_instance_method.rb +11 -0
- data/spec/fixtures/hook/method_named_call.rb +11 -0
- data/spec/fixtures/rails5_users_app/Gemfile +7 -3
- data/spec/fixtures/rails5_users_app/app/controllers/api/users_controller.rb +2 -0
- data/spec/fixtures/rails5_users_app/app/controllers/users_controller.rb +9 -1
- data/spec/fixtures/rails5_users_app/config/application.rb +2 -0
- data/spec/fixtures/rails5_users_app/create_app +8 -2
- data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_api_spec.rb +16 -3
- data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_spec.rb +2 -2
- data/spec/fixtures/rails5_users_app/spec/models/user_spec.rb +2 -12
- data/spec/fixtures/rails5_users_app/spec/rails_helper.rb +3 -9
- data/spec/fixtures/rails6_users_app/Gemfile +5 -4
- data/spec/fixtures/rails6_users_app/app/controllers/api/users_controller.rb +1 -0
- data/spec/fixtures/rails6_users_app/app/controllers/users_controller.rb +9 -1
- data/spec/fixtures/rails6_users_app/config/application.rb +2 -0
- data/spec/fixtures/rails6_users_app/create_app +8 -2
- data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_api_spec.rb +16 -3
- data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_spec.rb +2 -2
- data/spec/fixtures/rails6_users_app/spec/models/user_spec.rb +2 -12
- data/spec/fixtures/rails6_users_app/spec/rails_helper.rb +3 -9
- data/spec/hook_spec.rb +135 -18
- data/spec/record_net_http_spec.rb +160 -0
- data/spec/record_sql_rails_pg_spec.rb +1 -1
- data/spec/spec_helper.rb +16 -0
- data/test/expectations/openssl_test_key_sign1.json +2 -4
- data/test/fixtures/rspec_recorder/spec/decorated_hello_spec.rb +3 -3
- data/test/fixtures/rspec_recorder/spec/plain_hello_spec.rb +1 -1
- data/test/gem_test.rb +1 -1
- data/test/minitest_test.rb +1 -2
- data/test/rspec_test.rb +1 -20
- metadata +17 -13
- data/exe/appmap +0 -154
- data/spec/rspec_feature_metadata_spec.rb +0 -31
- data/test/cli_test.rb +0 -116
data/lib/appmap/record.rb
CHANGED
data/lib/appmap/rspec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'appmap/util'
|
4
|
+
require 'set'
|
4
5
|
|
5
6
|
module AppMap
|
6
7
|
# Integration of AppMap with RSpec. When enabled with APPMAP=true, the AppMap tracer will
|
@@ -13,58 +14,9 @@ module AppMap
|
|
13
14
|
AppMap.detect_metadata
|
14
15
|
end
|
15
16
|
|
16
|
-
module FeatureAnnotations
|
17
|
-
def feature
|
18
|
-
return nil unless annotations
|
19
|
-
|
20
|
-
annotations[:feature]
|
21
|
-
end
|
22
|
-
|
23
|
-
def labels
|
24
|
-
labels = metadata[:appmap]
|
25
|
-
if labels.is_a?(Array)
|
26
|
-
labels
|
27
|
-
elsif labels.is_a?(String) || labels.is_a?(Symbol)
|
28
|
-
[ labels ]
|
29
|
-
else
|
30
|
-
[]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def feature_group
|
35
|
-
return nil unless annotations
|
36
|
-
|
37
|
-
annotations[:feature_group]
|
38
|
-
end
|
39
|
-
|
40
|
-
def annotations
|
41
|
-
metadata.tap do |md|
|
42
|
-
description_args_hashes.each do |h|
|
43
|
-
md.merge! h
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def metadata
|
51
|
-
return {} unless example_obj.respond_to?(:metadata)
|
52
|
-
|
53
|
-
example_obj.metadata
|
54
|
-
end
|
55
|
-
|
56
|
-
def description_args_hashes
|
57
|
-
return [] unless example_obj.respond_to?(:metadata)
|
58
|
-
|
59
|
-
(example_obj.metadata[:description_args] || []).select { |arg| arg.is_a?(Hash) }
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
17
|
# ScopeExample and ScopeExampleGroup is a way to handle the weird way that RSpec
|
64
18
|
# stores the nested example names.
|
65
19
|
ScopeExample = Struct.new(:example) do
|
66
|
-
include FeatureAnnotations
|
67
|
-
|
68
20
|
alias_method :example_obj, :example
|
69
21
|
|
70
22
|
def description?
|
@@ -83,8 +35,6 @@ module AppMap
|
|
83
35
|
# As you can see here, the way that RSpec stores the example description and
|
84
36
|
# represents the example group hierarchy is pretty weird.
|
85
37
|
ScopeExampleGroup = Struct.new(:example_group) do
|
86
|
-
include FeatureAnnotations
|
87
|
-
|
88
38
|
alias_method :example_obj, :example_group
|
89
39
|
|
90
40
|
def description_args
|
@@ -133,13 +83,20 @@ module AppMap
|
|
133
83
|
page.driver.options[:http_client].instance_variable_get('@server_url').port
|
134
84
|
end
|
135
85
|
|
136
|
-
warn "Starting recording of example #{example}" if AppMap::RSpec::LOG
|
86
|
+
warn "Starting recording of example #{example}@#{source_location}" if AppMap::RSpec::LOG
|
137
87
|
@trace = AppMap.tracing.trace
|
138
88
|
@webdriver_port = webdriver_port.()
|
139
89
|
end
|
140
90
|
|
141
|
-
def
|
91
|
+
def source_location
|
92
|
+
result = example.location_rerun_argument.split(':')[0]
|
93
|
+
result = result[2..-1] if result.index('./') == 0
|
94
|
+
result
|
95
|
+
end
|
96
|
+
|
97
|
+
def finish(exception)
|
142
98
|
warn "Finishing recording of example #{example}" if AppMap::RSpec::LOG
|
99
|
+
warn "Exception: #{exception}" if exception && AppMap::RSpec::LOG
|
143
100
|
|
144
101
|
events = []
|
145
102
|
AppMap.tracing.delete @trace
|
@@ -148,22 +105,16 @@ module AppMap
|
|
148
105
|
|
149
106
|
AppMap::RSpec.add_event_methods @trace.event_methods
|
150
107
|
|
151
|
-
class_map = AppMap.class_map(@trace.event_methods
|
108
|
+
class_map = AppMap.class_map(@trace.event_methods)
|
152
109
|
|
153
110
|
description = []
|
154
111
|
scope = ScopeExample.new(example)
|
155
|
-
feature_group = feature = nil
|
156
112
|
|
157
|
-
labels = []
|
158
113
|
while scope
|
159
|
-
labels += scope.labels
|
160
114
|
description << scope.description
|
161
|
-
feature ||= scope.feature
|
162
|
-
feature_group ||= scope.feature_group
|
163
115
|
scope = scope.parent
|
164
116
|
end
|
165
117
|
|
166
|
-
labels = labels.map(&:to_s).map(&:strip).reject(&:blank?).map(&:downcase).uniq
|
167
118
|
description.reject!(&:nil?).reject!(&:blank?)
|
168
119
|
default_description = description.last
|
169
120
|
description.reverse!
|
@@ -177,24 +128,12 @@ module AppMap
|
|
177
128
|
|
178
129
|
full_description = normalize.call(description.join(' '))
|
179
130
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
|
-
feature_group ||= normalize.call(default_description).underscore.gsub('/', '_').humanize
|
189
|
-
feature_name = feature || compute_feature_name.call if feature_group
|
190
|
-
feature_name = normalize.call(feature_name) if feature_name
|
191
|
-
|
192
|
-
AppMap::RSpec.save full_description,
|
193
|
-
class_map,
|
194
|
-
events: events,
|
195
|
-
feature_name: feature_name,
|
196
|
-
feature_group_name: feature_group,
|
197
|
-
labels: labels.blank? ? nil : labels
|
131
|
+
AppMap::RSpec.save name: full_description,
|
132
|
+
class_map: class_map,
|
133
|
+
source_location: source_location,
|
134
|
+
test_status: exception ? 'failed' : 'succeeded',
|
135
|
+
exception: exception,
|
136
|
+
events: events
|
198
137
|
end
|
199
138
|
end
|
200
139
|
|
@@ -212,11 +151,11 @@ module AppMap
|
|
212
151
|
@recordings_by_example[example.object_id] = Recording.new(example)
|
213
152
|
end
|
214
153
|
|
215
|
-
def end_spec(example)
|
154
|
+
def end_spec(example, exception:)
|
216
155
|
recording = @recordings_by_example.delete(example.object_id)
|
217
156
|
return warn "No recording found for #{example}" unless recording
|
218
157
|
|
219
|
-
recording.finish
|
158
|
+
recording.finish exception
|
220
159
|
end
|
221
160
|
|
222
161
|
def config
|
@@ -227,13 +166,11 @@ module AppMap
|
|
227
166
|
@event_methods += event_methods
|
228
167
|
end
|
229
168
|
|
230
|
-
def save(
|
169
|
+
def save(name:, class_map:, source_location:, test_status:, exception:, events:)
|
231
170
|
metadata = AppMap::RSpec.metadata.tap do |m|
|
232
|
-
m[:name] =
|
171
|
+
m[:name] = name
|
172
|
+
m[:source_location] = source_location
|
233
173
|
m[:app] = AppMap.configuration.name
|
234
|
-
m[:feature] = feature_name if feature_name
|
235
|
-
m[:feature_group] = feature_group_name if feature_group_name
|
236
|
-
m[:labels] = labels if labels
|
237
174
|
m[:frameworks] ||= []
|
238
175
|
m[:frameworks] << {
|
239
176
|
name: 'rspec',
|
@@ -242,6 +179,13 @@ module AppMap
|
|
242
179
|
m[:recorder] = {
|
243
180
|
name: 'rspec'
|
244
181
|
}
|
182
|
+
m[:test_status] = test_status
|
183
|
+
if exception
|
184
|
+
m[:exception] = {
|
185
|
+
class: exception.class.name,
|
186
|
+
message: exception.to_s
|
187
|
+
}
|
188
|
+
end
|
245
189
|
end
|
246
190
|
|
247
191
|
appmap = {
|
@@ -250,14 +194,9 @@ module AppMap
|
|
250
194
|
classMap: class_map,
|
251
195
|
events: events
|
252
196
|
}.compact
|
253
|
-
fname = AppMap::Util.scenario_filename(
|
254
|
-
|
255
|
-
File.write(File.join(APPMAP_OUTPUT_DIR, fname), JSON.generate(appmap))
|
256
|
-
end
|
197
|
+
fname = AppMap::Util.scenario_filename(name)
|
257
198
|
|
258
|
-
|
259
|
-
class_map = AppMap.class_map(@event_methods)
|
260
|
-
save 'Inventory', class_map, labels: %w[inventory]
|
199
|
+
AppMap::Util.write_appmap(File.join(APPMAP_OUTPUT_DIR, fname), JSON.generate(appmap))
|
261
200
|
end
|
262
201
|
|
263
202
|
def enabled?
|
@@ -266,9 +205,6 @@ module AppMap
|
|
266
205
|
|
267
206
|
def run
|
268
207
|
init
|
269
|
-
at_exit do
|
270
|
-
print_inventory
|
271
|
-
end
|
272
208
|
end
|
273
209
|
end
|
274
210
|
end
|
@@ -290,7 +226,7 @@ if AppMap::RSpec.enabled?
|
|
290
226
|
begin
|
291
227
|
instance_exec(&fn)
|
292
228
|
ensure
|
293
|
-
AppMap::RSpec.end_spec example
|
229
|
+
AppMap::RSpec.end_spec example, exception: $!
|
294
230
|
end
|
295
231
|
end
|
296
232
|
end
|
data/lib/appmap/trace.rb
CHANGED
@@ -82,7 +82,8 @@ module AppMap
|
|
82
82
|
|
83
83
|
@last_package_for_thread[Thread.current.object_id] = package if package
|
84
84
|
@events << event
|
85
|
-
|
85
|
+
static = event.static if event.respond_to?(:static)
|
86
|
+
@methods << Trace::ScopedMethod.new(package, defined_class, method, static) \
|
86
87
|
if package && defined_class && method && (event.event == :call)
|
87
88
|
end
|
88
89
|
|
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
|
@@ -71,6 +79,35 @@ module AppMap
|
|
71
79
|
|
72
80
|
event
|
73
81
|
end
|
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
|
+
# Atomically writes AppMap data to +filename+.
|
97
|
+
def write_appmap(filename, appmap)
|
98
|
+
require 'fileutils'
|
99
|
+
require 'tmpdir'
|
100
|
+
|
101
|
+
# This is what Ruby Tempfile does; but we don't want the file to be unlinked.
|
102
|
+
mode = File::RDWR | File::CREAT | File::EXCL
|
103
|
+
::Dir::Tmpname.create([ 'appmap_', '.json' ]) do |tmpname|
|
104
|
+
tempfile = File.open(tmpname, mode)
|
105
|
+
tempfile.write(appmap)
|
106
|
+
tempfile.close
|
107
|
+
# Atomically move the tempfile into place.
|
108
|
+
FileUtils.mv tempfile.path, filename
|
109
|
+
end
|
110
|
+
end
|
74
111
|
end
|
75
112
|
end
|
76
113
|
end
|
data/lib/appmap/version.rb
CHANGED
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
|
+
|
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'rails_spec_helper'
|
2
2
|
|
3
|
-
describe '
|
3
|
+
describe 'Rails' do
|
4
4
|
%w[5 6].each do |rails_major_version| # rubocop:disable Metrics/BlockLength
|
5
|
-
context "
|
6
|
-
include_context 'Rails app pg database', "spec/fixtures/rails#{rails_major_version}_users_app"
|
5
|
+
context "#{rails_major_version}" do
|
6
|
+
include_context 'Rails app pg database', "spec/fixtures/rails#{rails_major_version}_users_app" unless use_existing_data?
|
7
|
+
|
7
8
|
def run_spec(spec_name)
|
8
|
-
FileUtils.rm_rf tmpdir
|
9
|
-
FileUtils.mkdir_p tmpdir
|
10
9
|
cmd = <<~CMD.gsub "\n", ' '
|
11
10
|
docker-compose run --rm -e RAILS_ENV=test -e APPMAP=true
|
12
11
|
-v #{File.absolute_path tmpdir}:/app/tmp app ./bin/rspec #{spec_name}
|
@@ -18,25 +17,32 @@ describe 'AbstractControllerBase' do
|
|
18
17
|
'tmp/spec/AbstractControllerBase'
|
19
18
|
end
|
20
19
|
|
20
|
+
unless use_existing_data?
|
21
|
+
before(:all) do
|
22
|
+
FileUtils.rm_rf tmpdir
|
23
|
+
FileUtils.mkdir_p tmpdir
|
24
|
+
run_spec 'spec/controllers/users_controller_spec.rb'
|
25
|
+
run_spec 'spec/controllers/users_controller_api_spec.rb'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
21
29
|
let(:appmap) { JSON.parse File.read File.join tmpdir, 'appmap/rspec', appmap_json_file }
|
30
|
+
let(:appmap_json_path) { File.join(tmpdir, 'appmap/rspec', appmap_json_file) }
|
31
|
+
let(:appmap) { JSON.parse File.read(appmap_json_path) }
|
22
32
|
let(:events) { appmap['events'] }
|
23
33
|
|
24
|
-
describe '
|
25
|
-
describe 'creating
|
26
|
-
before(:all) { run_spec 'spec/controllers/users_controller_api_spec.rb:8' }
|
34
|
+
describe 'an API route' do
|
35
|
+
describe 'creating an object' do
|
27
36
|
let(:appmap_json_file) do
|
28
37
|
'Api_UsersController_POST_api_users_with_required_parameters_creates_a_user.appmap.json'
|
29
38
|
end
|
30
39
|
|
31
|
-
it '
|
32
|
-
expect(File).to exist(File.join(tmpdir, 'appmap/rspec/Inventory.appmap.json'))
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'message fields are recorded in the appmap' do
|
40
|
+
it 'http_server_request is recorded in the appmap' do
|
36
41
|
expect(events).to include(
|
37
42
|
hash_including(
|
38
43
|
'http_server_request' => hash_including(
|
39
44
|
'request_method' => 'POST',
|
45
|
+
'normalized_path_info' => '/api/users(.:format)',
|
40
46
|
'path_info' => '/api/users'
|
41
47
|
),
|
42
48
|
'message' => include(
|
@@ -53,12 +59,17 @@ describe 'AbstractControllerBase' do
|
|
53
59
|
'object_id' => Integer
|
54
60
|
)
|
55
61
|
)
|
56
|
-
)
|
62
|
+
)
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'http_server_response is recorded in the appmap' do
|
67
|
+
expect(events).to include(
|
57
68
|
hash_including(
|
58
|
-
'http_server_response' =>
|
59
|
-
'
|
60
|
-
'mime_type' => 'application/json; charset=utf-8'
|
61
|
-
|
69
|
+
'http_server_response' => hash_including(
|
70
|
+
'status_code' => 201,
|
71
|
+
'mime_type' => 'application/json; charset=utf-8',
|
72
|
+
)
|
62
73
|
)
|
63
74
|
)
|
64
75
|
end
|
@@ -70,7 +81,7 @@ describe 'AbstractControllerBase' do
|
|
70
81
|
'defined_class' => 'Api::UsersController',
|
71
82
|
'method_id' => 'build_user',
|
72
83
|
'path' => 'app/controllers/api/users_controller.rb',
|
73
|
-
'lineno' =>
|
84
|
+
'lineno' => Integer,
|
74
85
|
'static' => false,
|
75
86
|
'parameters' => include(
|
76
87
|
'name' => 'params',
|
@@ -93,10 +104,47 @@ describe 'AbstractControllerBase' do
|
|
93
104
|
'elapsed' => Numeric
|
94
105
|
)
|
95
106
|
end
|
107
|
+
|
108
|
+
context 'with an object-style message' do
|
109
|
+
let(:appmap_json_file) { 'Api_UsersController_POST_api_users_with_required_parameters_with_object-style_parameters_creates_a_user.appmap.json' }
|
110
|
+
|
111
|
+
it 'message properties are recorded in the appmap' do
|
112
|
+
expect(events).to include(
|
113
|
+
hash_including(
|
114
|
+
'message' => include(
|
115
|
+
hash_including(
|
116
|
+
'name' => 'user',
|
117
|
+
'properties' => [
|
118
|
+
{ 'name' => 'login', 'class' => 'String' },
|
119
|
+
{ 'name' => 'password', 'class' => 'String' }
|
120
|
+
]
|
121
|
+
)
|
122
|
+
)
|
123
|
+
)
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'listing objects' do
|
130
|
+
context 'with a custom header' do
|
131
|
+
let(:appmap_json_file) { 'Api_UsersController_GET_api_users_with_a_custom_header_lists_the_users.appmap.json' }
|
132
|
+
|
133
|
+
it 'custom header is recorded in the appmap' do
|
134
|
+
expect(events).to include(
|
135
|
+
hash_including(
|
136
|
+
'http_server_request' => hash_including(
|
137
|
+
'headers' => hash_including('X-Sandwich' => 'turkey')
|
138
|
+
)
|
139
|
+
)
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
96
143
|
end
|
144
|
+
end
|
97
145
|
|
98
|
-
|
99
|
-
|
146
|
+
describe 'a UI route' do
|
147
|
+
describe 'rendering a page' do
|
100
148
|
let(:appmap_json_file) do
|
101
149
|
'UsersController_GET_users_login_shows_the_user.appmap.json'
|
102
150
|
end
|
@@ -107,16 +155,15 @@ describe 'AbstractControllerBase' do
|
|
107
155
|
'http_server_request' => {
|
108
156
|
'request_method' => 'GET',
|
109
157
|
'path_info' => '/users/alice',
|
110
|
-
'normalized_path_info' => '/users/:id(.:format)'
|
158
|
+
'normalized_path_info' => '/users/:id(.:format)',
|
159
|
+
'headers' => {
|
160
|
+
'Host' => 'test.host',
|
161
|
+
'User-Agent' => 'Rails Testing'
|
162
|
+
}
|
111
163
|
}
|
112
164
|
)
|
113
165
|
)
|
114
166
|
end
|
115
|
-
end
|
116
|
-
|
117
|
-
describe 'listing users' do
|
118
|
-
before(:all) { run_spec 'spec/controllers/users_controller_spec.rb:11' }
|
119
|
-
let(:appmap_json_file) { 'UsersController_GET_users_lists_the_users.appmap.json' }
|
120
167
|
|
121
168
|
it 'records and labels view rendering' do
|
122
169
|
expect(events).to include hash_including(
|
@@ -128,7 +175,7 @@ describe 'AbstractControllerBase' do
|
|
128
175
|
'lineno' => Integer,
|
129
176
|
'static' => false
|
130
177
|
)
|
131
|
-
|
178
|
+
|
132
179
|
expect(appmap['classMap']).to include hash_including(
|
133
180
|
'name' => 'action_view',
|
134
181
|
'children' => include(hash_including(
|
@@ -142,7 +189,7 @@ describe 'AbstractControllerBase' do
|
|
142
189
|
))
|
143
190
|
))
|
144
191
|
)
|
145
|
-
end
|
192
|
+
end
|
146
193
|
end
|
147
194
|
end
|
148
195
|
end
|