appmap 0.37.2 → 0.41.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -1
  3. data/.travis.yml +2 -23
  4. data/CHANGELOG.md +23 -0
  5. data/CONTRIBUTING.md +22 -0
  6. data/README.md +102 -54
  7. data/Rakefile +3 -3
  8. data/lib/appmap/class_map.rb +25 -8
  9. data/lib/appmap/config.rb +54 -26
  10. data/lib/appmap/hook.rb +18 -3
  11. data/lib/appmap/hook/method.rb +18 -12
  12. data/lib/appmap/rails/request_handler.rb +17 -3
  13. data/lib/appmap/railtie.rb +1 -5
  14. data/lib/appmap/trace.rb +18 -7
  15. data/lib/appmap/version.rb +2 -2
  16. data/spec/abstract_controller_base_spec.rb +125 -64
  17. data/spec/config_spec.rb +1 -0
  18. data/spec/fixtures/hook/exclude.rb +15 -0
  19. data/spec/fixtures/hook/labels.rb +6 -0
  20. data/spec/fixtures/rails5_users_app/Gemfile +3 -4
  21. data/spec/fixtures/rails5_users_app/app/controllers/users_controller.rb +8 -0
  22. data/spec/fixtures/rails5_users_app/appmap.yml +5 -1
  23. data/spec/fixtures/rails5_users_app/config/application.rb +2 -0
  24. data/spec/fixtures/rails5_users_app/config/routes.rb +1 -1
  25. data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_api_spec.rb +1 -1
  26. data/spec/fixtures/rails5_users_app/spec/controllers/users_controller_spec.rb +27 -0
  27. data/spec/fixtures/rails6_users_app/Gemfile +3 -4
  28. data/spec/fixtures/rails6_users_app/app/controllers/users_controller.rb +8 -0
  29. data/spec/fixtures/rails6_users_app/appmap.yml +6 -1
  30. data/spec/fixtures/rails6_users_app/config/application.rb +2 -0
  31. data/spec/fixtures/rails6_users_app/config/routes.rb +1 -1
  32. data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_api_spec.rb +1 -1
  33. data/spec/fixtures/rails6_users_app/spec/controllers/users_controller_spec.rb +27 -0
  34. data/spec/hook_spec.rb +69 -47
  35. data/spec/rails_spec_helper.rb +2 -2
  36. data/spec/record_sql_rails_pg_spec.rb +1 -1
  37. data/spec/rspec_feature_metadata_spec.rb +1 -1
  38. data/spec/spec_helper.rb +1 -0
  39. metadata +7 -68
  40. data/spec/abstract_controller4_base_spec.rb +0 -66
  41. data/spec/fixtures/rails4_users_app/.gitignore +0 -13
  42. data/spec/fixtures/rails4_users_app/.rbenv-gemsets +0 -2
  43. data/spec/fixtures/rails4_users_app/.ruby-version +0 -1
  44. data/spec/fixtures/rails4_users_app/Dockerfile +0 -30
  45. data/spec/fixtures/rails4_users_app/Dockerfile.pg +0 -3
  46. data/spec/fixtures/rails4_users_app/Gemfile +0 -77
  47. data/spec/fixtures/rails4_users_app/README.rdoc +0 -28
  48. data/spec/fixtures/rails4_users_app/Rakefile +0 -6
  49. data/spec/fixtures/rails4_users_app/app/assets/images/.keep +0 -0
  50. data/spec/fixtures/rails4_users_app/app/assets/javascripts/application.js +0 -16
  51. data/spec/fixtures/rails4_users_app/app/assets/stylesheets/application.css +0 -15
  52. data/spec/fixtures/rails4_users_app/app/controllers/api/users_controller.rb +0 -27
  53. data/spec/fixtures/rails4_users_app/app/controllers/application_controller.rb +0 -5
  54. data/spec/fixtures/rails4_users_app/app/controllers/concerns/.keep +0 -0
  55. data/spec/fixtures/rails4_users_app/app/controllers/health_controller.rb +0 -5
  56. data/spec/fixtures/rails4_users_app/app/controllers/users_controller.rb +0 -5
  57. data/spec/fixtures/rails4_users_app/app/helpers/application_helper.rb +0 -2
  58. data/spec/fixtures/rails4_users_app/app/mailers/.keep +0 -0
  59. data/spec/fixtures/rails4_users_app/app/models/.keep +0 -0
  60. data/spec/fixtures/rails4_users_app/app/models/concerns/.keep +0 -0
  61. data/spec/fixtures/rails4_users_app/app/models/user.rb +0 -18
  62. data/spec/fixtures/rails4_users_app/app/views/layouts/application.html.haml +0 -7
  63. data/spec/fixtures/rails4_users_app/app/views/users/index.html.haml +0 -7
  64. data/spec/fixtures/rails4_users_app/appmap.yml +0 -3
  65. data/spec/fixtures/rails4_users_app/bin/rails +0 -9
  66. data/spec/fixtures/rails4_users_app/bin/setup +0 -29
  67. data/spec/fixtures/rails4_users_app/bin/spring +0 -17
  68. data/spec/fixtures/rails4_users_app/config.ru +0 -4
  69. data/spec/fixtures/rails4_users_app/config/application.rb +0 -26
  70. data/spec/fixtures/rails4_users_app/config/boot.rb +0 -3
  71. data/spec/fixtures/rails4_users_app/config/database.yml +0 -18
  72. data/spec/fixtures/rails4_users_app/config/environment.rb +0 -5
  73. data/spec/fixtures/rails4_users_app/config/environments/development.rb +0 -41
  74. data/spec/fixtures/rails4_users_app/config/environments/production.rb +0 -79
  75. data/spec/fixtures/rails4_users_app/config/environments/test.rb +0 -42
  76. data/spec/fixtures/rails4_users_app/config/initializers/assets.rb +0 -11
  77. data/spec/fixtures/rails4_users_app/config/initializers/backtrace_silencers.rb +0 -7
  78. data/spec/fixtures/rails4_users_app/config/initializers/cookies_serializer.rb +0 -3
  79. data/spec/fixtures/rails4_users_app/config/initializers/filter_parameter_logging.rb +0 -4
  80. data/spec/fixtures/rails4_users_app/config/initializers/inflections.rb +0 -16
  81. data/spec/fixtures/rails4_users_app/config/initializers/mime_types.rb +0 -4
  82. data/spec/fixtures/rails4_users_app/config/initializers/session_store.rb +0 -3
  83. data/spec/fixtures/rails4_users_app/config/initializers/to_time_preserves_timezone.rb +0 -10
  84. data/spec/fixtures/rails4_users_app/config/initializers/wrap_parameters.rb +0 -14
  85. data/spec/fixtures/rails4_users_app/config/locales/en.yml +0 -23
  86. data/spec/fixtures/rails4_users_app/config/routes.rb +0 -12
  87. data/spec/fixtures/rails4_users_app/config/secrets.yml +0 -22
  88. data/spec/fixtures/rails4_users_app/create_app +0 -23
  89. data/spec/fixtures/rails4_users_app/db/migrate/20191127112304_create_users.rb +0 -10
  90. data/spec/fixtures/rails4_users_app/db/schema.rb +0 -26
  91. data/spec/fixtures/rails4_users_app/db/seeds.rb +0 -7
  92. data/spec/fixtures/rails4_users_app/docker-compose.yml +0 -26
  93. data/spec/fixtures/rails4_users_app/lib/assets/.keep +0 -0
  94. data/spec/fixtures/rails4_users_app/lib/tasks/.keep +0 -0
  95. data/spec/fixtures/rails4_users_app/log/.keep +0 -0
  96. data/spec/fixtures/rails4_users_app/public/404.html +0 -67
  97. data/spec/fixtures/rails4_users_app/public/422.html +0 -67
  98. data/spec/fixtures/rails4_users_app/public/500.html +0 -66
  99. data/spec/fixtures/rails4_users_app/public/favicon.ico +0 -0
  100. data/spec/fixtures/rails4_users_app/public/robots.txt +0 -5
  101. data/spec/fixtures/rails4_users_app/spec/controllers/users_controller_api_spec.rb +0 -49
  102. data/spec/fixtures/rails4_users_app/spec/rails_helper.rb +0 -95
  103. data/spec/fixtures/rails4_users_app/spec/spec_helper.rb +0 -96
  104. data/spec/fixtures/rails4_users_app/test/fixtures/users.yml +0 -9
  105. data/spec/record_sql_rails4_pg_spec.rb +0 -75
data/spec/config_spec.rb CHANGED
@@ -7,6 +7,7 @@ require 'appmap/config'
7
7
  describe AppMap::Config, docker: false do
8
8
  it 'loads from a Hash' do
9
9
  config_data = {
10
+ exclude: [],
10
11
  name: 'test',
11
12
  packages: [
12
13
  {
@@ -0,0 +1,15 @@
1
+ class ExcludeTest
2
+ def instance_method
3
+ 'instance_method'
4
+ end
5
+
6
+ class << self
7
+ def singleton_method
8
+ 'singleton_method'
9
+ end
10
+ end
11
+
12
+ def self.cls_method
13
+ 'class_method'
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ # @label has-cls-label
2
+ class ClassWithLabel
3
+ # @label has-fn-label
4
+ def fn_with_label
5
+ end
6
+ end
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
3
 
4
- gem 'rails', '~> 6'
4
+ gem 'rails', '~> 5'
5
5
 
6
6
  gem 'haml-rails'
7
7
 
@@ -33,11 +33,10 @@ appmap_options = \
33
33
  { path: appmap_path }
34
34
  else
35
35
  {}
36
- end.merge(require: %w[appmap appmap/railtie])
37
-
38
- gem 'appmap', appmap_options
36
+ end.merge(require: %w[appmap])
39
37
 
40
38
  group :development, :test do
39
+ gem 'appmap', appmap_options
41
40
  gem 'cucumber-rails', require: false
42
41
  gem 'rspec-rails'
43
42
  # Required for Sequel, since without ActiveRecord, the Rails transactional fixture support
@@ -2,4 +2,12 @@ class UsersController < ApplicationController
2
2
  def index
3
3
  @users = User.all
4
4
  end
5
+
6
+ def show
7
+ if (@user = User[login: params[:id]])
8
+ render plain: @user
9
+ else
10
+ render plain: 'Not found', status: 404
11
+ end
12
+ end
5
13
  end
@@ -1,3 +1,7 @@
1
1
  name: rails5_users_app
2
2
  packages:
3
- - path: app
3
+ - path: app/models
4
+ labels: [ mvc.model ]
5
+ - path: app/controllers
6
+ labels: [ mvc.controller ]
7
+ - gem: sequel
@@ -19,6 +19,8 @@ when 'activerecord'
19
19
  require 'active_record/railtie'
20
20
  end
21
21
 
22
+ require 'appmap/railtie' if defined?(AppMap)
23
+
22
24
  # require "active_storage/engine"
23
25
  # require "action_mailer/railtie"
24
26
  # require "action_cable/engine"
@@ -3,7 +3,7 @@ Rails.application.routes.draw do
3
3
  resources :users, only: %i[index create]
4
4
  end
5
5
 
6
- resources :users, only: %i[index]
6
+ resources :users, only: %i[index show]
7
7
 
8
8
  get 'health', to: 'health#show'
9
9
 
@@ -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
- post :index, params: {}
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,27 @@
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
+
17
+ describe 'GET /users/:login', feature: 'Show a user' do
18
+ before do
19
+ User.create login: 'alice'
20
+ end
21
+
22
+ it 'shows the user' do
23
+ get :show, params: { id: 'alice' }
24
+ expect(response).to be_ok
25
+ end
26
+ end
27
+ end
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
3
 
4
4
  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
5
- gem 'rails', '~> 5.2.3'
5
+ gem 'rails', '~> 6'
6
6
 
7
7
  gem 'haml-rails'
8
8
 
@@ -34,11 +34,10 @@ appmap_options = \
34
34
  { path: appmap_path }
35
35
  else
36
36
  {}
37
- end.merge(require: %w[appmap appmap/railtie])
38
-
39
- gem 'appmap', appmap_options
37
+ end.merge(require: %w[appmap])
40
38
 
41
39
  group :development, :test do
40
+ gem 'appmap', appmap_options
42
41
  gem 'cucumber-rails', require: false
43
42
  gem 'rspec-rails'
44
43
  # Required for Sequel, since without ActiveRecord, the Rails transactional fixture support
@@ -2,4 +2,12 @@ class UsersController < ApplicationController
2
2
  def index
3
3
  @users = User.all
4
4
  end
5
+
6
+ def show
7
+ if (@user = User[login: params[:id]])
8
+ render plain: @user
9
+ else
10
+ render plain: 'Not found', status: 404
11
+ end
12
+ end
5
13
  end
@@ -1,3 +1,8 @@
1
1
  name: rails6_users_app
2
2
  packages:
3
- - path: app
3
+ - path: app/models
4
+ labels: [ mvc.model ]
5
+ - path: app/controllers
6
+ labels: [ mvc.controller ]
7
+ - gem: sequel
8
+
@@ -19,6 +19,8 @@ when 'activerecord'
19
19
  require 'active_record/railtie'
20
20
  end
21
21
 
22
+ require 'appmap/railtie' if defined?(AppMap)
23
+
22
24
  # require "active_storage/engine"
23
25
  # require "action_mailer/railtie"
24
26
  # require "action_cable/engine"
@@ -3,7 +3,7 @@ Rails.application.routes.draw do
3
3
  resources :users, only: %i[index create]
4
4
  end
5
5
 
6
- resources :users, only: %i[index]
6
+ resources :users, only: %i[index show]
7
7
 
8
8
  get 'health', to: 'health#show'
9
9
 
@@ -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
- post :index, params: {}
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,27 @@
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
+
17
+ describe 'GET /users/:login', feature: 'Show a user' do
18
+ before do
19
+ User.create login: 'alice'
20
+ end
21
+
22
+ it 'shows the user' do
23
+ get :show, params: { id: 'alice' }
24
+ expect(response).to be_ok
25
+ end
26
+ end
27
+ end
data/spec/hook_spec.rb CHANGED
@@ -52,15 +52,51 @@ 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
61
61
  AppMap.configuration = nil
62
62
  end
63
63
 
64
+ it 'excludes named classes and methods' do
65
+ load 'spec/fixtures/hook/exclude.rb'
66
+ package = AppMap::Config::Package.build_from_path('spec/fixtures/hook/exclude.rb')
67
+ config = AppMap::Config.new('hook_spec', [ package ], %w[ExcludeTest])
68
+ AppMap.configuration = config
69
+
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
72
+ end
73
+
74
+ it 'parses labels from comments' do
75
+ _, tracer = invoke_test_file 'spec/fixtures/hook/labels.rb' do
76
+ ClassWithLabel.new.fn_with_label
77
+ end
78
+ class_map = AppMap.class_map(tracer.event_methods).to_yaml
79
+ expect(Diffy::Diff.new(<<~YAML, class_map).to_s).to eq('')
80
+ ---
81
+ - :name: spec/fixtures/hook/labels.rb
82
+ :type: package
83
+ :children:
84
+ - :name: ClassWithLabel
85
+ :type: class
86
+ :children:
87
+ - :name: fn_with_label
88
+ :type: function
89
+ :location: spec/fixtures/hook/labels.rb:4
90
+ :static: false
91
+ :labels:
92
+ - has-fn-label
93
+ :comment: "# @label has-fn-label\\n"
94
+ :source: |2
95
+ def fn_with_label
96
+ end
97
+ YAML
98
+ end
99
+
64
100
  it 'hooks an instance method that takes no arguments' do
65
101
  events_yaml = <<~YAML
66
102
  ---
@@ -517,24 +553,6 @@ describe 'AppMap class Hooking', docker: false do
517
553
  events_yaml = <<~YAML
518
554
  ---
519
555
  - :id: 1
520
- :event: :call
521
- :defined_class: NoToSMethod
522
- :method_id: respond_to?
523
- :path: spec/fixtures/hook/exception_method.rb
524
- :lineno: 24
525
- :static: false
526
- :parameters:
527
- - :name: :args
528
- :class: Array
529
- :value: "[:to_s]"
530
- :kind: :rest
531
- :receiver:
532
- :class: Class
533
- :value: NoToSMethod
534
- - :id: 2
535
- :event: :return
536
- :parent_id: 1
537
- - :id: 3
538
556
  :event: :call
539
557
  :defined_class: NoToSMethod
540
558
  :method_id: say_hello
@@ -545,9 +563,9 @@ describe 'AppMap class Hooking', docker: false do
545
563
  :receiver:
546
564
  :class: Class
547
565
  :value: NoToSMethod
548
- - :id: 4
566
+ - :id: 2
549
567
  :event: :return
550
- :parent_id: 3
568
+ :parent_id: 1
551
569
  :return_value:
552
570
  :class: String
553
571
  :value: hello
@@ -565,24 +583,6 @@ describe 'AppMap class Hooking', docker: false do
565
583
  events_yaml = <<~YAML
566
584
  ---
567
585
  - :id: 1
568
- :event: :call
569
- :defined_class: NoToSMethod
570
- :method_id: respond_to?
571
- :path: spec/fixtures/hook/exception_method.rb
572
- :lineno: 24
573
- :static: false
574
- :parameters:
575
- - :name: :args
576
- :class: Array
577
- :value: "[:to_s]"
578
- :kind: :rest
579
- :receiver:
580
- :class: Class
581
- :value: "*Error inspecting variable*"
582
- - :id: 2
583
- :event: :return
584
- :parent_id: 1
585
- - :id: 3
586
586
  :event: :call
587
587
  :defined_class: InspectRaises
588
588
  :method_id: say_hello
@@ -593,9 +593,9 @@ describe 'AppMap class Hooking', docker: false do
593
593
  :receiver:
594
594
  :class: Class
595
595
  :value: "*Error inspecting variable*"
596
- - :id: 4
596
+ - :id: 2
597
597
  :event: :return
598
- :parent_id: 3
598
+ :parent_id: 1
599
599
  :return_value:
600
600
  :class: String
601
601
  :value: hello
@@ -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', events_yaml do
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
- config, tracer = invoke_test_file 'spec/fixtures/hook/compare.rb' do
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
- spec = Gem::Specification.find_by_name('activesupport')
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[provider.secure_compare])
819
841
  end
820
842
  end
821
843
 
@@ -30,7 +30,7 @@ def run_cmd(*cmd, &failed)
30
30
  end
31
31
 
32
32
  shared_context 'Rails app pg database' do |fixture_dir|
33
- let(:fixture_dir) { fixture_dir }
33
+ define_method(:fixture_dir) { fixture_dir }
34
34
 
35
35
  before(:all) do
36
36
  print_pg_logs = lambda do
@@ -40,7 +40,7 @@ shared_context 'Rails app pg database' do |fixture_dir|
40
40
  puts logs
41
41
  end
42
42
 
43
- Dir.chdir fixture_dir do
43
+ Dir.chdir fixture_dir do
44
44
  run_cmd 'docker-compose down -v'
45
45
  cmd = 'docker-compose up -d pg'
46
46
  run_cmd cmd