Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 72c90c0

Browse files
committed
add new profiler class
1 parent 88ab5fa commit 72c90c0

File tree

5 files changed

+130
-0
lines changed

5 files changed

+130
-0
lines changed

lib/rspec/core.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
option_parser
3232
configuration_options
3333
runner
34+
profiler
3435
example
3536
shared_example_group
3637
example_group

lib/rspec/core/configuration.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,18 @@ def profile_examples
827827
end
828828
end
829829

830+
# @private
831+
def profiler
832+
@profiler ||=
833+
begin
834+
if value_for(:profile_examples) { @profile_examples }
835+
Profiler.new
836+
else
837+
NoProfiler.new
838+
end
839+
end
840+
end
841+
830842
# @private
831843
def files_or_directories_to_run=(*files)
832844
files = files.flatten

lib/rspec/core/profiler.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module RSpec
2+
module Core
3+
# @private
4+
class NoProfiler
5+
def example_groups
6+
{}
7+
end
8+
end
9+
10+
# @private
11+
class Profiler
12+
Formatters.register self, :example_group_started, :example_group_finished, :example_started
13+
14+
def initialize
15+
@example_groups = {}
16+
end
17+
18+
attr_reader :example_groups
19+
20+
def example_group_started(notification)
21+
@example_groups[notification.group.id] = Hash.new(0)
22+
@example_groups[notification.group.id][:start] = Time.now
23+
@example_groups[notification.group.id][:description] = notification.group.top_level_description
24+
end
25+
26+
def example_group_finished(notification)
27+
@example_groups[notification.group.id][:total_time] = Time.now - @example_groups[notification.group.id][:start]
28+
end
29+
30+
def example_started(notification)
31+
#todo: maybe move example_group.parent_groups.last to an example or notification method like example.last_anscestor_groupdd
32+
group = notification.example.example_group.parent_groups.last.id
33+
@example_groups[group][:count] += 1
34+
end
35+
36+
end
37+
end
38+
end

lib/rspec/core/reporter.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def initialize(configuration)
1818
@failed_examples = []
1919
@pending_examples = []
2020
@duration = @start = @load_time = nil
21+
register_listener @configuration.profiler, *Formatters::Loader.formatters[@configuration.profiler.class]
2122
end
2223

2324
# @private

spec/rspec/core/profiler_spec.rb

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
require 'rspec/core/profiler'
2+
3+
RSpec.describe 'RSpec::Core::NoProfiler' do
4+
let(:no_profiler) { RSpec::Core::NoProfiler.new }
5+
6+
it 'has an empty hash of example_groups' do
7+
expect(no_profiler.example_groups).to be_empty.and be_a Hash
8+
end
9+
end
10+
11+
RSpec.describe 'RSpec::Core::Profiler' do
12+
let(:profiler) { RSpec::Core::Profiler.new }
13+
14+
it 'has starts with an empty hash of example_groups' do
15+
expect(profiler.example_groups).to be_empty.and be_a Hash
16+
end
17+
18+
context 'when hooked into the reporter' do
19+
include FormatterSupport
20+
21+
let(:id) { 42 }
22+
let(:description ) { "My Group" }
23+
let(:now) { ::Time.now }
24+
25+
before do
26+
allow(::RSpec::Core::Time).to receive(:now) { now }
27+
end
28+
29+
def group
30+
@group ||=
31+
begin
32+
group = super
33+
allow(group).to receive_messages(id: id, top_level_description: description)
34+
group
35+
end
36+
end
37+
38+
describe '#example_group_started' do
39+
it 'records example groups start time and description via id' do
40+
expect {
41+
profiler.example_group_started group_notification group
42+
}.to change { profiler.example_groups[id] }.to include(
43+
start: now, description: description
44+
)
45+
end
46+
end
47+
48+
describe '#example_group_finished' do
49+
before do
50+
profiler.example_group_started group_notification group
51+
allow(::RSpec::Core::Time).to receive(:now) { now + 1 }
52+
end
53+
54+
it 'records example groups total time and description via id' do
55+
expect {
56+
profiler.example_group_finished group_notification group
57+
}.to change { profiler.example_groups[id] }.to include(
58+
total_time: 1.0
59+
)
60+
end
61+
end
62+
63+
describe '#example_started' do
64+
let(:example) { new_example }
65+
before do
66+
allow(example).to receive(:example_group) { group }
67+
allow(group).to receive(:parent_groups) { [group] }
68+
profiler.example_group_started group_notification group
69+
end
70+
71+
it 'increments the count of examples for its parent group' do
72+
expect {
73+
profiler.example_started example_notification example
74+
}.to change { profiler.example_groups[id][:count] }.by 1
75+
end
76+
end
77+
end
78+
end

0 commit comments

Comments
 (0)