appmap 0.41.2 → 0.45.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.releaserc.yml +11 -0
  3. data/.travis.yml +23 -2
  4. data/CHANGELOG.md +40 -0
  5. data/README.md +36 -6
  6. data/README_CI.md +29 -0
  7. data/Rakefile +4 -2
  8. data/appmap.gemspec +5 -3
  9. data/lib/appmap.rb +4 -2
  10. data/lib/appmap/class_map.rb +7 -10
  11. data/lib/appmap/config.rb +98 -28
  12. data/lib/appmap/cucumber.rb +1 -1
  13. data/lib/appmap/event.rb +18 -0
  14. data/lib/appmap/handler/function.rb +19 -0
  15. data/lib/appmap/handler/net_http.rb +107 -0
  16. data/lib/appmap/hook.rb +42 -22
  17. data/lib/appmap/hook/method.rb +5 -7
  18. data/lib/appmap/minitest.rb +35 -30
  19. data/lib/appmap/rails/request_handler.rb +30 -17
  20. data/lib/appmap/record.rb +1 -1
  21. data/lib/appmap/rspec.rb +32 -96
  22. data/lib/appmap/trace.rb +2 -1
  23. data/lib/appmap/util.rb +39 -2
  24. data/lib/appmap/version.rb +2 -2
  25. data/release.sh +17 -0
  26. data/spec/abstract_controller_base_spec.rb +76 -29
  27. data/spec/class_map_spec.rb +3 -11
  28. data/spec/config_spec.rb +33 -1
  29. data/spec/fixtures/hook/custom_instance_method.rb +11 -0
  30. data/spec/fixtures/hook/method_named_call.rb +11 -0
  31. data/spec/fixtures/rails5_users_app/Gemfile +7 -3
  32. data/spec/fixtures/rails5_users_app/app/controllers/api/users_controller.rb +2 -0
  33. data/spec/fixtures/rails5_users_app/app/controllers/users_controller.rb +9 -1
  34. data/spec/fixtures/rails5_users_app/config/application.rb +2 -0
  35. data/spec/fixtures/rails5_users_app/create_app +8 -2
  36. data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_api_spec.rb +16 -3
  37. data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_spec.rb +2 -2
  38. data/spec/fixtures/rails5_users_app/spec/models/user_spec.rb +2 -12
  39. data/spec/fixtures/rails5_users_app/spec/rails_helper.rb +3 -9
  40. data/spec/fixtures/rails6_users_app/Gemfile +5 -4
  41. data/spec/fixtures/rails6_users_app/app/controllers/api/users_controller.rb +1 -0
  42. data/spec/fixtures/rails6_users_app/app/controllers/users_controller.rb +9 -1
  43. data/spec/fixtures/rails6_users_app/config/application.rb +2 -0
  44. data/spec/fixtures/rails6_users_app/create_app +8 -2
  45. data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_api_spec.rb +16 -3
  46. data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_spec.rb +2 -2
  47. data/spec/fixtures/rails6_users_app/spec/models/user_spec.rb +2 -12
  48. data/spec/fixtures/rails6_users_app/spec/rails_helper.rb +3 -9
  49. data/spec/hook_spec.rb +135 -18
  50. data/spec/record_net_http_spec.rb +160 -0
  51. data/spec/record_sql_rails_pg_spec.rb +1 -1
  52. data/spec/spec_helper.rb +16 -0
  53. data/test/expectations/openssl_test_key_sign1.json +2 -4
  54. data/test/fixtures/rspec_recorder/spec/decorated_hello_spec.rb +3 -3
  55. data/test/fixtures/rspec_recorder/spec/plain_hello_spec.rb +1 -1
  56. data/test/gem_test.rb +1 -1
  57. data/test/minitest_test.rb +1 -2
  58. data/test/rspec_test.rb +1 -20
  59. metadata +17 -13
  60. data/exe/appmap +0 -154
  61. data/spec/rspec_feature_metadata_spec.rb +0 -31
  62. data/test/cli_test.rb +0 -116
@@ -4,18 +4,10 @@ require 'spec_helper'
4
4
 
5
5
  describe 'AppMap::ClassMap' do
6
6
  describe '.build_from_methods' do
7
- it 'includes source code if available' do
8
- map = AppMap.class_map([scoped_method(method(:test_method))])
7
+ it 'includes method comment' do
8
+ map = AppMap.class_map([scoped_method((method :test_method))])
9
9
  function = dig_map(map, 5)[0]
10
- expect(function[:source]).to include 'test method body'
11
- expect(function[:comment]).to include 'test method comment'
12
- end
13
-
14
- it 'can omit source code even if available' do
15
- map = AppMap.class_map([scoped_method((method :test_method))], include_source: false)
16
- function = dig_map(map, 5)[0]
17
- expect(function).to_not include(:source)
18
- expect(function).to_not include(:comment)
10
+ expect(function).to include(:comment)
19
11
  end
20
12
 
21
13
  # test method comment
data/spec/config_spec.rb CHANGED
@@ -17,10 +17,42 @@ describe AppMap::Config, docker: false do
17
17
  path: 'path-2',
18
18
  exclude: [ 'exclude-1' ]
19
19
  }
20
+ ],
21
+ functions: [
22
+ {
23
+ package: 'pkg',
24
+ class: 'cls',
25
+ function: 'fn',
26
+ label: 'lbl'
27
+ }
20
28
  ]
21
29
  }.deep_stringify_keys!
22
30
  config = AppMap::Config.load(config_data)
23
31
 
24
- expect(config.to_h.deep_stringify_keys!).to eq(config_data)
32
+ config_expectation = {
33
+ exclude: [],
34
+ name: 'test',
35
+ packages: [
36
+ {
37
+ path: 'path-1',
38
+ handler_class: 'AppMap::Handler::Function'
39
+ },
40
+ {
41
+ path: 'path-2',
42
+ handler_class: 'AppMap::Handler::Function',
43
+ exclude: [ 'exclude-1' ]
44
+ }
45
+ ],
46
+ functions: [
47
+ {
48
+ package: 'pkg',
49
+ class: 'cls',
50
+ functions: [ :fn ],
51
+ labels: ['lbl']
52
+ }
53
+ ]
54
+ }.deep_stringify_keys!
55
+
56
+ expect(config.to_h.deep_stringify_keys!).to eq(config_expectation)
25
57
  end
26
58
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CustomInstanceMethod
4
+ def to_s
5
+ 'CustomInstance Method fixture'
6
+ end
7
+
8
+ def say_default
9
+ 'default'
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MethodNamedCall
4
+ def to_s
5
+ 'MethodNamedCall'
6
+ end
7
+
8
+ def call(a, b, c, d, e)
9
+ [ a, b, c, d, e ].join(' ')
10
+ end
11
+ end
@@ -39,12 +39,16 @@ group :development, :test do
39
39
  gem 'appmap', appmap_options
40
40
  gem 'cucumber-rails', require: false
41
41
  gem 'rspec-rails'
42
- # Required for Sequel, since without ActiveRecord, the Rails transactional fixture support
43
- # isn't activated.
44
- gem 'database_cleaner'
45
42
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
46
43
  gem 'pry-byebug'
47
44
  end
48
45
 
46
+ group :test do
47
+ # Require only one of these.
48
+ # 'database_cleaner' requries 'database_cleaner-active_record', so don't require it.
49
+ gem 'database_cleaner-active_record', require: false
50
+ gem 'database_cleaner-sequel', require: false
51
+ end
52
+
49
53
  group :development do
50
54
  end
@@ -6,6 +6,8 @@ module Api
6
6
  end
7
7
 
8
8
  def create
9
+ params = self.params.key?(:user) ? self.params[:user] : self.params
10
+
9
11
  @user = build_user(params.slice(:login).to_unsafe_h)
10
12
  unless @user.valid?
11
13
  error = {
@@ -4,7 +4,15 @@ class UsersController < ApplicationController
4
4
  end
5
5
 
6
6
  def show
7
- if (@user = User[login: params[:id]])
7
+ find_user = lambda do |id|
8
+ if User.respond_to?(:[])
9
+ User[login: id]
10
+ else
11
+ User.find_by_login!(id)
12
+ end
13
+ end
14
+
15
+ if (@user = find_user.(params[:id]))
8
16
  render plain: @user
9
17
  else
10
18
  render plain: 'Not found', status: 404
@@ -15,8 +15,10 @@ case orm_module
15
15
  when 'sequel'
16
16
  require 'sequel-rails'
17
17
  require 'sequel_secure_password'
18
+ require 'database_cleaner-sequel' if Rails.env.test?
18
19
  when 'activerecord'
19
20
  require 'active_record/railtie'
21
+ require 'database_cleaner-active_record' if Rails.env.test?
20
22
  end
21
23
 
22
24
  require 'appmap/railtie' if defined?(AppMap)
@@ -16,11 +16,17 @@ if [[ $? != 0 ]]; then
16
16
  exit 1
17
17
  fi
18
18
 
19
- psql -h pg -U postgres -c "create database app_development"
20
- psql -h pg -U postgres -c "create database app_test"
19
+ # Required for migrations
20
+ export ORM_MODULE=sequel
21
21
 
22
+ set +e
23
+ psql -h pg -U postgres -c "drop database if exists app_development"
24
+ psql -h pg -U postgres -c "drop database if exists app_test"
22
25
  set -e
23
26
 
27
+ psql -h pg -U postgres -c "create database app_development"
28
+ psql -h pg -U postgres -c "create database app_test"
29
+
24
30
  RAILS_ENV=development ./bin/rake db:migrate
25
31
  RAILS_ENV=test ./bin/rake db:migrate
26
32
 
@@ -1,13 +1,19 @@
1
1
  require 'rails_helper'
2
2
  require 'rack/test'
3
3
 
4
- RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller, appmap: true do
5
- describe 'POST /api/users', feature: 'Create a user' do
4
+ RSpec.describe Api::UsersController, type: :controller do
5
+ describe 'POST /api/users' do
6
6
  describe 'with required parameters' do
7
7
  it 'creates a user' do
8
8
  post :create, params: { login: 'alice', password: 'foobar' }
9
9
  expect(response.status).to eq(201)
10
10
  end
11
+ describe 'with object-style parameters' do
12
+ it 'creates a user' do
13
+ post :create, params: { user: { login: 'alice', password: 'foobar' } }
14
+ expect(response.status).to eq(201)
15
+ end
16
+ end
11
17
  end
12
18
  describe 'with a missing parameter' do
13
19
  it 'reports error 422' do
@@ -16,7 +22,7 @@ RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller,
16
22
  end
17
23
  end
18
24
  end
19
- describe 'GET /api/users', feature: 'List users' do
25
+ describe 'GET /api/users' do
20
26
  before do
21
27
  post :create, params: { login: 'alice' }
22
28
  end
@@ -25,5 +31,12 @@ RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller,
25
31
  users = JSON.parse(response.body)
26
32
  expect(users.map { |r| r['login'] }).to include('alice')
27
33
  end
34
+ describe 'with a custom header' do
35
+ it 'lists the users' do
36
+ request.headers['X-Sandwich'] = 'turkey'
37
+ get :index, params: {}
38
+ expect(response.status).to eq(200)
39
+ end
40
+ end
28
41
  end
29
42
  end
@@ -4,7 +4,7 @@ require 'rack/test'
4
4
  RSpec.describe UsersController, type: :controller do
5
5
  render_views
6
6
 
7
- describe 'GET /users', feature: 'Show all users' do
7
+ describe 'GET /users' do
8
8
  before do
9
9
  User.create login: 'alice'
10
10
  end
@@ -14,7 +14,7 @@ RSpec.describe UsersController, type: :controller do
14
14
  end
15
15
  end
16
16
 
17
- describe 'GET /users/:login', feature: 'Show a user' do
17
+ describe 'GET /users/:login' do
18
18
  before do
19
19
  User.create login: 'alice'
20
20
  end
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe User, feature_group: 'User', appmap: true do
3
+ describe User do
4
4
  # TODO: appmap/rspec doesn't handle shared_examples_for 100% correctly yet.
5
5
  # In my tests, only one of these two tests will be emitted as an appmap.
6
6
  shared_examples_for 'creates the user' do |username|
@@ -11,17 +11,7 @@ describe User, feature_group: 'User', appmap: true do
11
11
  end
12
12
  end
13
13
 
14
- describe 'creation', feature: 'Create a user' do
15
- context 'using shared_examples_for' do
16
- # AppMap.
17
- # context "with username 'alice'" do
18
- # it_should_behave_like 'creates the user', 'alice'
19
- # end
20
- # context "with username 'bob'" do
21
- # it_should_behave_like 'creates the user', 'bob'
22
- # end
23
- end
24
-
14
+ describe 'creation' do
25
15
  # So, instead of shared_examples_for, let's go with a simple method
26
16
  # containing the assertions. The method can be called from within an example.
27
17
  def save_and_verify
@@ -45,7 +45,6 @@ RSpec.configure do |config|
45
45
  # arbitrary gems may also be filtered via:
46
46
  # config.filter_gems_from_backtrace("gem name")
47
47
 
48
-
49
48
  DatabaseCleaner.allow_remote_database_url = true
50
49
 
51
50
  config.before(:suite) do
@@ -54,13 +53,8 @@ RSpec.configure do |config|
54
53
  end
55
54
 
56
55
  config.around :each do |example|
57
- # Enable the use of 'return' from a guard
58
- -> {
59
- return example.run unless %i[model controller].member?(example.metadata[:type])
60
-
61
- DatabaseCleaner.cleaning do
62
- example.run
63
- end
64
- }.call
56
+ DatabaseCleaner.cleaning do
57
+ example.run
58
+ end
65
59
  end
66
60
  end
@@ -1,7 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
3
 
4
- # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
5
4
  gem 'rails', '~> 6'
6
5
 
7
6
  gem 'haml-rails'
@@ -40,12 +39,14 @@ group :development, :test do
40
39
  gem 'appmap', appmap_options
41
40
  gem 'cucumber-rails', require: false
42
41
  gem 'rspec-rails'
43
- # Required for Sequel, since without ActiveRecord, the Rails transactional fixture support
44
- # isn't activated.
45
- gem 'database_cleaner'
46
42
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
47
43
  gem 'pry-byebug'
48
44
  end
49
45
 
46
+ group :test do
47
+ gem 'database_cleaner-active_record', require: false
48
+ gem 'database_cleaner-sequel', require: false
49
+ end
50
+
50
51
  group :development do
51
52
  end
@@ -6,6 +6,7 @@ module Api
6
6
  end
7
7
 
8
8
  def create
9
+ params = self.params.key?(:user) ? self.params[:user] : self.params
9
10
  @user = build_user(params.slice(:login).to_unsafe_h)
10
11
  unless @user.valid?
11
12
  error = {
@@ -4,7 +4,15 @@ class UsersController < ApplicationController
4
4
  end
5
5
 
6
6
  def show
7
- if (@user = User[login: params[:id]])
7
+ find_user = lambda do |id|
8
+ if User.respond_to?(:[])
9
+ User[login: id]
10
+ else
11
+ User.find_by_login!(id)
12
+ end
13
+ end
14
+
15
+ if (@user = find_user.(params[:id]))
8
16
  render plain: @user
9
17
  else
10
18
  render plain: 'Not found', status: 404
@@ -15,8 +15,10 @@ case orm_module
15
15
  when 'sequel'
16
16
  require 'sequel-rails'
17
17
  require 'sequel_secure_password'
18
+ require 'database_cleaner-sequel' if Rails.env.test?
18
19
  when 'activerecord'
19
20
  require 'active_record/railtie'
21
+ require 'database_cleaner-active_record' if Rails.env.test?
20
22
  end
21
23
 
22
24
  require 'appmap/railtie' if defined?(AppMap)
@@ -16,11 +16,17 @@ if [[ $? != 0 ]]; then
16
16
  exit 1
17
17
  fi
18
18
 
19
- psql -h pg -U postgres -c "create database app_development"
20
- psql -h pg -U postgres -c "create database app_test"
19
+ # Required for migrations
20
+ export ORM_MODULE=sequel
21
21
 
22
+ set +e
23
+ psql -h pg -U postgres -c "drop database if exists app_development"
24
+ psql -h pg -U postgres -c "drop database if exists app_test"
22
25
  set -e
23
26
 
27
+ psql -h pg -U postgres -c "create database app_development"
28
+ psql -h pg -U postgres -c "create database app_test"
29
+
24
30
  RAILS_ENV=development ./bin/rake db:migrate
25
31
  RAILS_ENV=test ./bin/rake db:migrate
26
32
 
@@ -1,13 +1,19 @@
1
1
  require 'rails_helper'
2
2
  require 'rack/test'
3
3
 
4
- RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller, appmap: true do
5
- describe 'POST /api/users', feature: 'Create a user' do
4
+ RSpec.describe Api::UsersController, type: :controller do
5
+ describe 'POST /api/users' do
6
6
  describe 'with required parameters' do
7
7
  it 'creates a user' do
8
8
  post :create, params: { login: 'alice', password: 'foobar' }
9
9
  expect(response.status).to eq(201)
10
10
  end
11
+ describe 'with object-style parameters' do
12
+ it 'creates a user' do
13
+ post :create, params: { user: { login: 'alice', password: 'foobar' } }
14
+ expect(response.status).to eq(201)
15
+ end
16
+ end
11
17
  end
12
18
  describe 'with a missing parameter' do
13
19
  it 'reports error 422' do
@@ -16,7 +22,7 @@ RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller,
16
22
  end
17
23
  end
18
24
  end
19
- describe 'GET /api/users', feature: 'List users' do
25
+ describe 'GET /api/users' do
20
26
  before do
21
27
  post :create, params: { login: 'alice' }
22
28
  end
@@ -25,5 +31,12 @@ RSpec.describe Api::UsersController, feature_group: 'Users', type: :controller,
25
31
  users = JSON.parse(response.body)
26
32
  expect(users.map { |r| r['login'] }).to include('alice')
27
33
  end
34
+ describe 'with a custom header' do
35
+ it 'lists the users' do
36
+ request.headers['X-Sandwich'] = 'turkey'
37
+ get :index, params: {}
38
+ expect(response.status).to eq(200)
39
+ end
40
+ end
28
41
  end
29
42
  end
@@ -4,7 +4,7 @@ require 'rack/test'
4
4
  RSpec.describe UsersController, type: :controller do
5
5
  render_views
6
6
 
7
- describe 'GET /users', feature: 'Show all users' do
7
+ describe 'GET /users' do
8
8
  before do
9
9
  User.create login: 'alice'
10
10
  end
@@ -14,7 +14,7 @@ RSpec.describe UsersController, type: :controller do
14
14
  end
15
15
  end
16
16
 
17
- describe 'GET /users/:login', feature: 'Show a user' do
17
+ describe 'GET /users/:login' do
18
18
  before do
19
19
  User.create login: 'alice'
20
20
  end
@@ -1,6 +1,6 @@
1
1
  require 'rails_helper'
2
2
 
3
- describe User, feature_group: 'User', appmap: true do
3
+ describe User do
4
4
  # TODO: appmap/rspec doesn't handle shared_examples_for 100% correctly yet.
5
5
  # In my tests, only one of these two tests will be emitted as an appmap.
6
6
  shared_examples_for 'creates the user' do |username|
@@ -11,17 +11,7 @@ describe User, feature_group: 'User', appmap: true do
11
11
  end
12
12
  end
13
13
 
14
- describe 'creation', feature: 'Create a user' do
15
- context 'using shared_examples_for' do
16
- # AppMap.
17
- # context "with username 'alice'" do
18
- # it_should_behave_like 'creates the user', 'alice'
19
- # end
20
- # context "with username 'bob'" do
21
- # it_should_behave_like 'creates the user', 'bob'
22
- # end
23
- end
24
-
14
+ describe 'creation' do
25
15
  # So, instead of shared_examples_for, let's go with a simple method
26
16
  # containing the assertions. The method can be called from within an example.
27
17
  def save_and_verify