test-prof 0.1.0.pre5 → 0.1.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.
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