test-prof 0.1.0.pre5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +16 -4
  4. data/assets/flamegraph.demo.html +173 -0
  5. data/assets/flamegraph.template.html +196 -0
  6. data/assets/src/d3-tip.js +352 -0
  7. data/assets/src/d3-tip.min.js +1 -0
  8. data/assets/src/d3.flameGraph.css +92 -0
  9. data/assets/src/d3.flameGraph.js +459 -0
  10. data/assets/src/d3.flameGraph.min.css +1 -0
  11. data/assets/src/d3.flameGraph.min.js +1 -0
  12. data/assets/src/d3.v4.min.js +8 -0
  13. data/guides/any_fixture.md +1 -1
  14. data/guides/event_prof.md +30 -0
  15. data/guides/factory_default.md +109 -0
  16. data/guides/factory_prof.md +85 -0
  17. data/guides/rubocop.md +48 -0
  18. data/guides/ruby_prof.md +2 -0
  19. data/guides/stack_prof.md +5 -1
  20. data/guides/tag_prof.md +52 -0
  21. data/guides/tests_sampling.md +24 -0
  22. data/lib/test_prof.rb +31 -7
  23. data/lib/test_prof/cops/rspec/aggregate_failures.rb +140 -0
  24. data/lib/test_prof/event_prof/custom_events.rb +3 -3
  25. data/lib/test_prof/event_prof/custom_events/factory_create.rb +10 -8
  26. data/lib/test_prof/event_prof/custom_events/sidekiq_inline.rb +10 -8
  27. data/lib/test_prof/event_prof/custom_events/sidekiq_jobs.rb +12 -10
  28. data/lib/test_prof/event_prof/rspec.rb +5 -1
  29. data/lib/test_prof/factory_default.rb +58 -0
  30. data/lib/test_prof/factory_default/factory_girl_patch.rb +22 -0
  31. data/lib/test_prof/factory_doctor.rb +11 -9
  32. data/lib/test_prof/factory_doctor/rspec.rb +5 -3
  33. data/lib/test_prof/factory_prof.rb +140 -0
  34. data/lib/test_prof/factory_prof/factory_girl_patch.rb +12 -0
  35. data/lib/test_prof/factory_prof/printers/flamegraph.rb +71 -0
  36. data/lib/test_prof/factory_prof/printers/simple.rb +28 -0
  37. data/lib/test_prof/recipes/minitest/sample.rb +29 -0
  38. data/lib/test_prof/recipes/rspec/factory_default.rb +9 -0
  39. data/lib/test_prof/recipes/rspec/sample.rb +13 -0
  40. data/lib/test_prof/rspec_stamp/rspec.rb +5 -1
  41. data/lib/test_prof/rubocop.rb +3 -0
  42. data/lib/test_prof/ruby_prof.rb +6 -12
  43. data/lib/test_prof/stack_prof.rb +14 -7
  44. data/lib/test_prof/tag_prof.rb +8 -0
  45. data/lib/test_prof/tag_prof/rspec.rb +84 -0
  46. data/lib/test_prof/version.rb +1 -1
  47. metadata +48 -41
  48. data/.gitignore +0 -10
  49. data/.rspec +0 -2
  50. data/.rubocop.yml +0 -69
  51. data/.travis.yml +0 -5
  52. data/Gemfile +0 -4
  53. data/Rakefile +0 -8
  54. data/bin/setup +0 -8
  55. data/circle.yml +0 -11
  56. data/spec/integrations/any_fixture_spec.rb +0 -11
  57. data/spec/integrations/before_all_spec.rb +0 -11
  58. data/spec/integrations/event_prof_spec.rb +0 -100
  59. data/spec/integrations/factory_doctor_spec.rb +0 -20
  60. data/spec/integrations/fixtures/rspec/any_fixture_fixture.rb +0 -37
  61. data/spec/integrations/fixtures/rspec/before_all_fixture.rb +0 -32
  62. data/spec/integrations/fixtures/rspec/event_prof_factory_create_fixture.rb +0 -23
  63. data/spec/integrations/fixtures/rspec/event_prof_fixture.rb +0 -51
  64. data/spec/integrations/fixtures/rspec/event_prof_sidekiq_fixture.rb +0 -53
  65. data/spec/integrations/fixtures/rspec/factory_doctor_fixture.rb +0 -33
  66. data/spec/integrations/fixtures/rspec/rspec_stamp_fixture_tmpl.rb +0 -33
  67. data/spec/integrations/rspec_stamp_spec.rb +0 -53
  68. data/spec/spec_helper.rb +0 -38
  69. data/spec/support/ar_models.rb +0 -43
  70. data/spec/support/instrumenter_stub.rb +0 -19
  71. data/spec/support/integration_helpers.rb +0 -13
  72. data/spec/support/transactional_context.rb +0 -11
  73. data/spec/test_prof/any_fixture_spec.rb +0 -66
  74. data/spec/test_prof/event_prof_spec.rb +0 -138
  75. data/spec/test_prof/ext/float_duration_spec.rb +0 -12
  76. data/spec/test_prof/factory_doctor_spec.rb +0 -84
  77. data/spec/test_prof/rspec_stamp/parser_spec.rb +0 -58
  78. data/spec/test_prof/rspec_stamp_spec.rb +0 -281
  79. data/spec/test_prof/ruby_prof_spec.rb +0 -109
  80. data/spec/test_prof/stack_prof_spec.rb +0 -73
  81. data/spec/test_prof_spec.rb +0 -23
  82. data/test-prof.gemspec +0 -35
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
4
- require_relative "../../../support/ar_models"
5
- require "test-prof"
6
-
7
- describe "User" do
8
- let(:user) { FactoryGirl.create(:user) }
9
-
10
- it "generates random names" do
11
- user2 = FactoryGirl.create(:user)
12
- expect(user.name).not_to eq user2.name
13
- end
14
-
15
- it "validates name" do
16
- user.name = ''
17
- expect(user).not_to be_valid
18
- end
19
-
20
- it "creates and reloads user" do
21
- user = FactoryGirl.create(:user, name: 'John')
22
- expect(User.find(user.id).name).to eq 'John'
23
- end
24
-
25
- it "clones" do
26
- expect(user.clone.name).to include("(cloned)")
27
- end
28
-
29
- it "is ignored", :fd_ignore do
30
- user.name = ''
31
- expect(user).not_to be_valid
32
- end
33
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../../../lib", __FILE__)
4
- require "active_support"
5
- require "test-prof"
6
-
7
- shared_context "fixxer", fix: :me do
8
- before { @value = true }
9
- end
10
-
11
- describe "Something" do
12
- it "fail me" do
13
- expect(@value).to eq true
14
- end
15
-
16
- it "always passes" do
17
- expect(true).to eq true
18
- end
19
-
20
- specify '
21
- you
22
- can
23
- not
24
- patch me
25
- ' do
26
- expect(@value).to eq true
27
- end
28
-
29
- context "nested context" do
30
- subject { @value }
31
- specify { is_expected.to eq true }
32
- end
33
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe "RSpecStamp" do
6
- before do
7
- FileUtils.cp(
8
- File.expand_path("../../integrations/fixtures/rspec/rspec_stamp_fixture_tmpl.rb", __FILE__),
9
- File.expand_path("../../integrations/fixtures/rspec/rspec_stamp_fixture.rb", __FILE__)
10
- )
11
- end
12
-
13
- after do
14
- FileUtils.rm(
15
- File.expand_path("../../integrations/fixtures/rspec/rspec_stamp_fixture.rb", __FILE__)
16
- )
17
- end
18
-
19
- specify "it works", :aggregate_failures do
20
- output = run_rspec('rspec_stamp', success: false, env: { 'RSTAMP' => 'fix:me' })
21
-
22
- expect(output).to include("4 examples, 3 failures")
23
-
24
- expect(output).to include("RSpec Stamp results")
25
- expect(output).to include("Total patches: 3")
26
- expect(output).to include("Total files: 1")
27
- expect(output).to include("Failed patches: 1")
28
- expect(output).to include("Ignored files: 0")
29
-
30
- output2 = run_rspec('rspec_stamp', success: false)
31
-
32
- expect(output2).to include("4 examples, 1 failure")
33
- end
34
-
35
- specify "it works with dry-run", :aggregate_failures do
36
- output = run_rspec('rspec_stamp', success: false, env: { 'RSTAMP' => 'fix:me', 'RSTAMP_DRY_RUN' => '1' })
37
-
38
- expect(output).to include("4 examples, 3 failures")
39
-
40
- expect(output).to include("RSpec Stamp results")
41
- expect(output).to include("Total patches: 3")
42
- expect(output).to include("Total files: 1")
43
- expect(output).to include("Failed patches: 1")
44
- expect(output).to include("Ignored files: 0")
45
-
46
- expect(output).to include("(dry-run) Patching ./rspec_stamp_fixture.rb")
47
- expect(output).to include("Patched: it 'fail me', fix: :me do")
48
-
49
- output2 = run_rspec('rspec_stamp', success: false)
50
-
51
- expect(output2).to include("4 examples, 3 failures")
52
- end
53
- end
data/spec/spec_helper.rb DELETED
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
4
- require "test-prof"
5
- require "pry-byebug"
6
- require "open3"
7
-
8
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
9
-
10
- RSpec.configure do |config|
11
- config.mock_with :rspec
12
-
13
- config.order = :random
14
- config.filter_run focus: true
15
- config.run_all_when_everything_filtered = true
16
-
17
- config.define_derived_metadata(file_path: %r{/spec/integrations/}) do |metadata|
18
- metadata[:type] = :integration
19
- end
20
-
21
- config.include IntegrationHelpers, type: :integration
22
-
23
- config.before(:suite) do
24
- FileUtils.mkdir_p("tmp")
25
- end
26
-
27
- config.before(:each) do
28
- allow(TestProf).to receive(:require).and_return(true)
29
- # Clear global configuration
30
- TestProf.remove_instance_variable(:@config) if
31
- TestProf.instance_variable_defined?(:@config)
32
- TestProf.config.output = StringIO.new
33
- end
34
-
35
- config.after(:suite) do
36
- FileUtils.rm_rf("tmp")
37
- end
38
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_record"
4
- require "factory_girl"
5
-
6
- ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
7
-
8
- ActiveRecord::Schema.define do
9
- create_table :users do |t|
10
- t.string :name
11
- end
12
-
13
- create_table :posts do |t|
14
- t.text :text
15
- t.integer :user_id
16
- end
17
- end
18
-
19
- class User < ActiveRecord::Base
20
- validates :name, presence: true
21
- has_many :posts, dependent: :destroy
22
-
23
- def clone
24
- copy = dup
25
- copy.name = "#{name} (cloned)"
26
- copy
27
- end
28
- end
29
-
30
- class Post < ActiveRecord::Base
31
- belongs_to :user
32
- end
33
-
34
- FactoryGirl.define do
35
- factory :user do
36
- name { |n| "John #{n}" }
37
- end
38
-
39
- factory :post do
40
- text { |n| "Post ##{n}}" }
41
- user
42
- end
43
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module InstrumenterStub
4
- class << self
5
- def subscribe(event, &block)
6
- listeners[event] = block
7
- end
8
-
9
- def notify(event, time)
10
- listeners[event].call(time)
11
- end
12
-
13
- private
14
-
15
- def listeners
16
- @listeners ||= {}
17
- end
18
- end
19
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module IntegrationHelpers
4
- def run_rspec(path, success: true, env: {})
5
- output, status = Open3.capture2(
6
- env,
7
- "rspec #{path}_fixture.rb",
8
- chdir: File.expand_path("../../integrations/fixtures/rspec", __FILE__)
9
- )
10
- expect(status).to be_success if success
11
- output
12
- end
13
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- shared_context "transactional", transactional: true do
4
- prepend_before(:each) do
5
- ActiveRecord::Base.connection.begin_transaction(joinable: false)
6
- end
7
-
8
- append_after(:each) do
9
- ActiveRecord::Base.connection.rollback_transaction
10
- end
11
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "test_prof/any_fixture"
5
-
6
- describe TestProf::AnyFixture, :transactional do
7
- subject { described_class }
8
-
9
- after { described_class.reset }
10
-
11
- describe "#register" do
12
- it "invokes block only once for the same id" do
13
- block = double('block', call: 1)
14
- block2 = double('block2', call: 2)
15
-
16
- expect(block).to receive(:call)
17
- expect(block2).not_to receive(:call)
18
-
19
- expect(subject.register(:test) { block.call })
20
- .to eq 1
21
-
22
- expect(subject.register(:test) { block2.call })
23
- .to eq 1
24
- end
25
- end
26
-
27
- describe "#clean" do
28
- it "tracks AR queries and delete affected tables" do
29
- # add a record outside of any fixture to check
30
- # that we delete all records from the tables
31
- FactoryGirl.create(:user)
32
-
33
- expect do
34
- subject.register(:user) { FactoryGirl.create(:user) }
35
- end.to change(User, :count).by(1)
36
-
37
- expect do
38
- subject.register(:post) { FactoryGirl.create(:post) }
39
- end.to change(User, :count).by(1)
40
- .and change(Post, :count).by(1)
41
-
42
- subject.clean
43
-
44
- # Try to re-register user - should have no effect
45
- subject.register(:user) { FactoryGirl.create(:user) }
46
-
47
- expect(User.count).to eq 0
48
- expect(Post.count).to eq 0
49
- end
50
- end
51
-
52
- describe "#reset" do
53
- it "delete affected tables and reset cache" do
54
- expect do
55
- subject.register(:user) { FactoryGirl.create(:user) }
56
- end.to change(User, :count).by(1)
57
-
58
- subject.reset
59
- expect(User.count).to eq 0
60
-
61
- subject.register(:user) { FactoryGirl.create(:user) }
62
-
63
- expect(User.count).to eq 1
64
- end
65
- end
66
- end
@@ -1,138 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe TestProf::EventProf do
6
- # Use fresh config all for every example
7
- after { described_class.remove_instance_variable(:@config) }
8
-
9
- before { stub_const("ActiveSupport::Notifications", double(subscribe: nil)) }
10
-
11
- subject { described_class.build }
12
-
13
- describe ".config" do
14
- specify "defaults", :aggregate_failiures do
15
- expect(subject.top_count).to eq 5
16
- expect(subject.rank_by).to eq :time
17
- end
18
- end
19
-
20
- describe ".build" do
21
- before { described_class.config.event = 'test.event' }
22
-
23
- it "subscribes to event" do
24
- expect(TestProf::EventProf::Instrumentations::ActiveSupport)
25
- .to receive(:subscribe).with('test.event')
26
- subject
27
- end
28
-
29
- it "sets options" do
30
- expect(subject.event).to eq 'test.event'
31
- expect(subject.rank_by).to eq :time
32
- expect(subject.top_count).to eq 5
33
- end
34
- end
35
-
36
- describe "#result" do
37
- let(:results) do
38
- described_class.config.event = 'test.event'
39
- described_class.config.instrumenter = InstrumenterStub
40
-
41
- subject
42
-
43
- subject.group_started 'A'
44
-
45
- subject.example_started 'A1'
46
- InstrumenterStub.notify 'test.event', 100
47
- subject.example_finished 'A1'
48
-
49
- subject.group_finished 'A'
50
-
51
- subject.group_started 'B'
52
-
53
- subject.example_started 'B1'
54
- InstrumenterStub.notify 'test.event', 140
55
- InstrumenterStub.notify 'test.event', 240
56
- subject.example_finished 'B1'
57
-
58
- subject.example_started 'B2'
59
- InstrumenterStub.notify 'test.event', 40
60
- subject.example_finished 'B2'
61
-
62
- subject.group_finished 'B'
63
-
64
- subject.group_started 'C'
65
-
66
- subject.example_started 'C1'
67
- InstrumenterStub.notify 'test.event', 400
68
- InstrumenterStub.notify 'test.event', 40
69
- subject.example_finished 'C1'
70
-
71
- subject.example_started 'C2'
72
- subject.example_finished 'C2'
73
-
74
- subject.group_finished 'C'
75
-
76
- subject.results
77
- end
78
-
79
- it "returns top slow groups and totals" do
80
- expect(results).to eq(
81
- groups: [
82
- { id: 'C', examples: 2, time: 440, count: 2 },
83
- { id: 'B', examples: 2, time: 420, count: 3 },
84
- { id: 'A', examples: 1, time: 100, count: 1 }
85
- ]
86
- )
87
- expect(subject.total_time).to eq 960
88
- expect(subject.total_count).to eq 6
89
- end
90
-
91
- context "when rank by count" do
92
- before { described_class.config.rank_by = :count }
93
-
94
- it "returns top groups by event occurances" do
95
- expect(results).to eq(
96
- groups: [
97
- { id: 'B', examples: 2, time: 420, count: 3 },
98
- { id: 'C', examples: 2, time: 440, count: 2 },
99
- { id: 'A', examples: 1, time: 100, count: 1 }
100
- ]
101
- )
102
- end
103
- end
104
-
105
- context "when top_count is specified" do
106
- before { described_class.config.top_count = 2 }
107
-
108
- it "returns top groups by event occurances" do
109
- expect(results).to eq(
110
- groups: [
111
- { id: 'C', examples: 2, time: 440, count: 2 },
112
- { id: 'B', examples: 2, time: 420, count: 3 }
113
- ]
114
- )
115
- end
116
- end
117
-
118
- context "when per_example is true" do
119
- before { described_class.config.per_example = true }
120
-
121
- it "returns top groups and examples" do
122
- expect(results).to eq(
123
- groups: [
124
- { id: 'C', examples: 2, time: 440, count: 2 },
125
- { id: 'B', examples: 2, time: 420, count: 3 },
126
- { id: 'A', examples: 1, time: 100, count: 1 }
127
- ],
128
- examples: [
129
- { id: 'C1', time: 440, count: 2 },
130
- { id: 'B1', time: 380, count: 2 },
131
- { id: 'A1', time: 100, count: 1 },
132
- { id: 'B2', time: 40, count: 1 }
133
- ]
134
- )
135
- end
136
- end
137
- end
138
- end