rspec_profiling 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjdkNDIyMmIzYWQ1YjFlZjgwYzEwOTFmZjgzZDY1YzM2N2NmZDI3Yw==
5
+ data.tar.gz: !binary |-
6
+ MTRmYWE0OWRkMmUzOTZlZjQ5MTQzYWE5MjZjMTg3N2JkZTY5NGMxYg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YWZkYmMzZjYzNWJkMjZmNzFhODFjZjJlMmFlNzExYTRmZmI4ZmY0MTU3NTNh
10
+ MzhmYzEwMGUyYjBmYmFkYTM3YzBlNTRhMWNhMjlkNzM4MDMwYWI2NTJiZDg5
11
+ NGFlYzk0YTEwOGE3MWYwNTdjNTY0MjBiYTlmNTJmMzJjOGUxNGI=
12
+ data.tar.gz: !binary |-
13
+ MTkyMmMxNWU2NDQyNDRkMzExNzgyMjRkNjExNzZhODhkMmM0MzJjYzdhNjQ2
14
+ MDYwMWQwZjExMGJlOTBkZGNkOWY5MjUyN2FhNTJmM2Q4ZmJkZjE1MTcyMTUw
15
+ ZWYzODE4NjNjOWI4NTA1NGFkODZiNmFkOGE1NmJlMmI3MGY5Mjc=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec_profiling.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ben Eddy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # RSpecProfiling
2
+
3
+ Collects profiles of RSpec test suites, enabling you to identify specs
4
+ with interesting attributes. For example, find the slowest specs, or the
5
+ spec which issues the most queries.
6
+
7
+ Collected attributes include:
8
+ - git commit SHA and date
9
+ - example file, line number and description
10
+ - example status (i.e. passed or failed)
11
+ - example time
12
+ - query count and time
13
+ - request count and time
14
+
15
+ ## Compatibility
16
+
17
+ RSpecProfiling should work with Rails >= 3.2 and RSpec >= 2.14.
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```
24
+ gem 'rspec_profiling'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ ```
30
+ bundle
31
+ ```
32
+
33
+ Require the gem to your `spec_helper.rb`.
34
+
35
+ ```
36
+ require "rspec_profiling/rspec"
37
+ ```
38
+
39
+ Lastly, run the installation rake tasks to initialize an empty database in
40
+ which results will be collected.
41
+
42
+ ```
43
+ bundle exec rake rspec_profiling:install
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ ### Choose a results collector
49
+
50
+ Results are collected just by running the specs.
51
+
52
+ #### SQLite3
53
+
54
+ By default, profiles are collected in an SQL database. Make sure you've
55
+ run the installation rake task before attempting.
56
+
57
+ You can review results by running the RSpecProfiling console.
58
+
59
+ ```
60
+ bundle exec rake rspec_profiling:console
61
+
62
+ > results.count
63
+ => 1970
64
+
65
+ > results.order(:query_count).last.to_s
66
+ => "Updating my account - ./spec/features/account_spec.rb:15"
67
+ ```
68
+
69
+ The console has a preloaded `results` variable.
70
+
71
+ ```
72
+ results.count
73
+ > 180
74
+ ```
75
+
76
+ #### CSV
77
+
78
+ You can configure `RSpecProfiling` to collect results in a CSV in your
79
+ `spec_helper.rb` file.
80
+
81
+ ```Ruby
82
+ RSpecProfiling.configure do |config|
83
+ config.collector = RSpecProfiling::Collectors::CSV
84
+ end
85
+
86
+ require "rspec_profiling/rspec"
87
+ ```
88
+
89
+ By default, the CSV is output to `cat tmp/spec_benchmarks.csv`.
90
+ Rerunning spec will overwrite the file. You can customize the CSV path
91
+ to, for example, include the sample time.
92
+
93
+ ```Ruby
94
+ RSpecProfiling.configure do |config|
95
+ config.collector = RSpecProfiling::Collectors::CSV
96
+ config.csv_path = ->{ "tmp/spec_benchmark_#{Time.now.to_i}" }
97
+ end
98
+
99
+ require "rspec_profiling/rspec"
100
+ ```
101
+
102
+ ## Configuration Options
103
+
104
+ Configuration is performed like this:
105
+
106
+ ```Ruby
107
+ RSpecProfiling.configure do |config|
108
+ config.<option> = <something>
109
+ end
110
+ ```
111
+
112
+ ### Options
113
+
114
+ - `db_path` - the location of the SQLite database file
115
+ - `table_name` - the database table name in which results are stored
116
+ - `csv_path` - the directory in which CSV files are dumped
117
+
118
+ ## Uninstalling
119
+
120
+ To remove the results database, run `bundle exec rake
121
+ rspec_profiling:uninstall`.
122
+
123
+ ## Contributing
124
+
125
+ 1. Fork it
126
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
127
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
128
+ 4. Push to the branch (`git push origin my-new-feature`)
129
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ import "./lib/tasks/rspec_profiling.rake"
@@ -0,0 +1,19 @@
1
+ require "ostruct"
2
+ require "rails"
3
+ require "rspec_profiling/config"
4
+ require "rspec_profiling/version"
5
+ require "rspec_profiling/run"
6
+ require "rspec_profiling/collectors/csv"
7
+ require "rspec_profiling/collectors/database"
8
+
9
+ module RspecProfiling
10
+ class Railtie < Rails::Railtie
11
+ railtie_name :rspec_profiling
12
+
13
+ rake_tasks do
14
+ load "tasks/rspec_profiling.rake"
15
+ end
16
+ end
17
+ end
18
+
19
+ RSpecProfiling = RspecProfiling
@@ -0,0 +1,49 @@
1
+ require "csv"
2
+
3
+ module RspecProfiling
4
+ module Collectors
5
+ class CSV
6
+ HEADERS = %w{
7
+ commit_sha
8
+ commit_date
9
+ file
10
+ line_number
11
+ description
12
+ status
13
+ time
14
+ query_count
15
+ query_time
16
+ request_count
17
+ request_time
18
+ }
19
+
20
+ def self.install
21
+ # no op
22
+ end
23
+
24
+ def self.uninstall
25
+ # no op
26
+ end
27
+
28
+ def self.reset
29
+ # no op
30
+ end
31
+
32
+ def insert(attributes)
33
+ output << HEADERS.map do |field|
34
+ attributes.fetch(field.to_sym)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def output
41
+ @output ||= ::CSV.open(path, "w").tap { |csv| csv << HEADERS }
42
+ end
43
+
44
+ def path
45
+ RspecProfiling.config.csv_path.call
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,98 @@
1
+ require "sqlite3"
2
+ require "active_record"
3
+
4
+ module RspecProfiling
5
+ module Collectors
6
+ class Database
7
+ def self.install
8
+ new.install
9
+ end
10
+
11
+ def self.uninstall
12
+ new.uninstall
13
+ end
14
+
15
+ def self.reset
16
+ new.results.destroy_all
17
+ end
18
+
19
+ def initialize
20
+ establish_connection
21
+ end
22
+
23
+ def install
24
+ return if prepared?
25
+
26
+ connection.create_table(table) do |t|
27
+ t.string :commit_sha
28
+ t.datetime :commit_date
29
+ t.text :file
30
+ t.integer :line_number
31
+ t.text :description
32
+ t.decimal :time
33
+ t.string :status
34
+ t.integer :query_count
35
+ t.decimal :query_time
36
+ t.integer :request_count
37
+ t.decimal :request_time
38
+ t.timestamps
39
+ end
40
+ end
41
+
42
+ def uninstall
43
+ connection.drop_table(table)
44
+ end
45
+
46
+ def insert(attributes)
47
+ results.create!(attributes.except(:created_at))
48
+ end
49
+
50
+ def results
51
+ @results ||= begin
52
+ establish_connection
53
+
54
+ Result.table_name = table
55
+ Result.attr_protected if Result.respond_to?(:attr_protected)
56
+ Result
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def prepared?
63
+ connection.table_exists?(table)
64
+ end
65
+
66
+ def connection
67
+ @connection ||= results.connection
68
+ end
69
+
70
+ def establish_connection
71
+ Result.establish_connection(
72
+ :adapter => "sqlite3",
73
+ :database => database
74
+ )
75
+ end
76
+
77
+ def table
78
+ RspecProfiling.config.table_name
79
+ end
80
+
81
+ def database
82
+ RspecProfiling.config.db_path
83
+ end
84
+
85
+ class Result < ActiveRecord::Base
86
+ def to_s
87
+ [description, location].join(" - ")
88
+ end
89
+
90
+ private
91
+
92
+ def location
93
+ [file, line_number].join(":")
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,14 @@
1
+ module RspecProfiling
2
+ def self.configure
3
+ yield config
4
+ end
5
+
6
+ def self.config
7
+ @config ||= OpenStruct.new({
8
+ collector: RspecProfiling::Collectors::Database,
9
+ db_path: 'tmp/rspec_profiling',
10
+ table_name: 'spec_profiling_results',
11
+ csv_path: Proc.new { 'tmp/spec_benchmarks.csv' }
12
+ })
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ def results
2
+ @results ||= RspecProfiling.config.collector.new.results
3
+ end
@@ -0,0 +1,15 @@
1
+ require "time"
2
+
3
+ module RspecProfiling
4
+ module CurrentCommit
5
+ extend self
6
+
7
+ def sha
8
+ `git rev-parse HEAD`
9
+ end
10
+
11
+ def time
12
+ Time.parse `git show -s --format=%ci #{sha}`
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,90 @@
1
+ require "benchmark"
2
+
3
+ module RspecProfiling
4
+ class Example
5
+ IGNORED_QUERIES_PATTERN = %r{(
6
+ pg_table|
7
+ pg_attribute|
8
+ pg_namespace|
9
+ show\stables|
10
+ pragma|
11
+ sqlite_master/rollback|
12
+ ^TRUNCATE TABLE|
13
+ ^ALTER TABLE|
14
+ ^BEGIN|
15
+ ^COMMIT|
16
+ ^ROLLBACK|
17
+ ^RELEASE|
18
+ ^SAVEPOINT
19
+ )}xi
20
+
21
+ def initialize(example)
22
+ @example = example
23
+ @counts = Hash.new(0)
24
+ end
25
+
26
+ def file
27
+ metadata[:file_path]
28
+ end
29
+
30
+ def line_number
31
+ metadata[:line_number]
32
+ end
33
+
34
+ def description
35
+ metadata[:full_description]
36
+ end
37
+
38
+ def status
39
+ execution_result.status
40
+ end
41
+
42
+ def time
43
+ execution_result.run_time
44
+ end
45
+
46
+ def query_count
47
+ counts[:query_count]
48
+ end
49
+
50
+ def query_time
51
+ counts[:query_time]
52
+ end
53
+
54
+ def request_count
55
+ counts[:request_count]
56
+ end
57
+
58
+ def request_time
59
+ counts[:request_time]
60
+ end
61
+
62
+ def log_query(query, start, finish)
63
+ unless query[:sql] =~ IGNORED_QUERIES_PATTERN
64
+ counts[:query_count] += 1
65
+ counts[:query_time] += (finish - start)
66
+ end
67
+ end
68
+
69
+ def log_request(request, start, finish)
70
+ counts[:request_count] += 1
71
+ counts[:request_time] += request[:view_runtime].to_f
72
+ end
73
+
74
+ private
75
+
76
+ attr_reader :example, :counts
77
+
78
+ def execution_result
79
+ @execution_result ||= begin
80
+ result = example.execution_result
81
+ result = OpenStruct.new(result) if result.is_a?(Hash)
82
+ result
83
+ end
84
+ end
85
+
86
+ def metadata
87
+ example.metadata
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,9 @@
1
+ require "rspec_profiling"
2
+
3
+ RSpec.configure do |config|
4
+ config.reporter.register_listener RspecProfiling::Run.new(RspecProfiling.config.collector.new),
5
+ :start,
6
+ :example_started,
7
+ :example_passed,
8
+ :example_failed
9
+ end
@@ -0,0 +1,55 @@
1
+ require "rspec_profiling/example"
2
+ require "rspec_profiling/current_commit"
3
+
4
+ module RspecProfiling
5
+ class Run
6
+ def initialize(collector)
7
+ @collector = collector
8
+ end
9
+
10
+ def start(*args)
11
+ start_counting_queries
12
+ start_counting_requests
13
+ end
14
+
15
+ def example_started(example)
16
+ example = example.example if example.respond_to?(:example)
17
+ @current_example = Example.new(example)
18
+ end
19
+
20
+ def example_finished(*args)
21
+ collector.insert({
22
+ commit_sha: CurrentCommit.sha,
23
+ commit_date: CurrentCommit.time,
24
+ file: @current_example.file,
25
+ line_number: @current_example.line_number,
26
+ description: @current_example.description,
27
+ status: @current_example.status,
28
+ time: @current_example.time,
29
+ query_count: @current_example.query_count,
30
+ query_time: @current_example.query_time,
31
+ request_count: @current_example.request_count,
32
+ request_time: @current_example.request_time
33
+ })
34
+ end
35
+
36
+ alias :example_passed :example_finished
37
+ alias :example_failed :example_finished
38
+
39
+ private
40
+
41
+ attr_reader :collector
42
+
43
+ def start_counting_queries
44
+ ActiveSupport::Notifications.subscribe("sql.active_record") do |name, start, finish, id, query|
45
+ @current_example.try(:log_query, query, start, finish)
46
+ end
47
+ end
48
+
49
+ def start_counting_requests
50
+ ActiveSupport::Notifications.subscribe("process_action.action_controller") do |name, start, finish, id, request|
51
+ @current_example.try(:log_request, request, start, finish)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module RspecProfiling
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,30 @@
1
+ require 'rake'
2
+
3
+ namespace :rspec_profiling do
4
+ desc "Install the collector"
5
+ task :install do
6
+ collector.install
7
+ end
8
+
9
+ desc "Uninstall the collector"
10
+ task :uninstall do
11
+ collector.uninstall
12
+ end
13
+
14
+ task :console do
15
+ require 'irb'
16
+ require 'irb/completion'
17
+ require 'rspec_profiling'
18
+ require 'rspec_profiling/console'
19
+ ARGV.clear
20
+ IRB.start
21
+ end
22
+
23
+ task :reset do
24
+ collector.reset
25
+ end
26
+
27
+ def collector
28
+ RspecProfiling.config.collector
29
+ end
30
+ end
data/rspec_profiling ADDED
File without changes
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec_profiling/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec_profiling"
8
+ spec.version = RspecProfiling::VERSION
9
+ spec.authors = ["Ben Eddy"]
10
+ spec.email = ["bae@foraker.com"]
11
+ spec.description = %q{Profile RSpec test suites}
12
+ spec.summary = %q{Profile RSpec test suites}
13
+ spec.homepage = "https://github.com/foraker/rspec_profiling"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "sqlite3"
22
+ spec.add_dependency "activerecord"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ end
@@ -0,0 +1,80 @@
1
+ require "rspec_profiling/config"
2
+ require "rspec_profiling/collectors/database"
3
+
4
+ module RspecProfiling
5
+ module Collectors
6
+ describe Database do
7
+ before(:all) { Database.install }
8
+ after(:all) { Database.uninstall }
9
+
10
+ describe "#insert" do
11
+ let(:collector) { described_class.new }
12
+ let(:result) { collector.results.first }
13
+
14
+ before do
15
+ collector.insert({
16
+ commit_sha: "ABC123",
17
+ commit_date: "Thu Dec 18 12:00:00 2012",
18
+ file: "/some/file.rb",
19
+ line_number: 10,
20
+ description: "Some spec",
21
+ time: 100,
22
+ status: :passed,
23
+ query_count: 10,
24
+ query_time: 50,
25
+ request_count: 1,
26
+ request_time: 400
27
+ })
28
+ end
29
+
30
+ it "records a single result" do
31
+ expect(collector.results.count).to eq 1
32
+ end
33
+
34
+ it "records the commit SHA" do
35
+ expect(result.commit_sha).to eq "ABC123"
36
+ end
37
+
38
+ it "records the commit date" do
39
+ expect(result.commit_date).to eq Time.utc(2012, 12, 18, 12)
40
+ end
41
+
42
+ it "records the file" do
43
+ expect(result.file).to eq "/some/file.rb"
44
+ end
45
+
46
+ it "records the line number" do
47
+ expect(result.line_number).to eq 10
48
+ end
49
+
50
+ it "records the description" do
51
+ expect(result.description).to eq "Some spec"
52
+ end
53
+
54
+ it "records the time" do
55
+ expect(result.time).to eq 100.0
56
+ end
57
+
58
+ it "records the passing status" do
59
+ expect(result.status).to eq 'passed'
60
+ end
61
+
62
+ it "records the query count" do
63
+ expect(result.query_count).to eq 10
64
+ end
65
+
66
+ it "records the query time" do
67
+ expect(result.query_time).to eq 50
68
+ end
69
+
70
+ it "records the request count" do
71
+ expect(result.request_count).to eq 1
72
+ end
73
+
74
+ it "records the request time" do
75
+ expect(result.request_time).to eq 400
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
data/spec/run_spec.rb ADDED
@@ -0,0 +1,135 @@
1
+ require "active_support/core_ext"
2
+ require "rspec_profiling/run"
3
+ require "time"
4
+ require "ostruct"
5
+
6
+ module RspecProfiling
7
+ describe Run do
8
+ def simulate_query(sql)
9
+ ActiveSupport::Notifications.instrument("sql.active_record", "sql", 100, 200, 1, {
10
+ sql: sql
11
+ })
12
+ end
13
+
14
+ def simulate_request
15
+ ActiveSupport::Notifications.instrument("process_action.action_controller", "request", 100, 400, 2, {
16
+ view_runtime: 10
17
+ })
18
+ end
19
+
20
+ describe "#run_example" do
21
+ let(:collector) { CollectorDouble.new }
22
+ let(:run) { described_class.new(collector) }
23
+ let(:result) { collector.results.first }
24
+ let(:commit) do
25
+ double({
26
+ sha: "abc123",
27
+ time: Time.new(2012, 12, 12)
28
+ })
29
+ end
30
+ let(:example) do
31
+ ExampleDouble.new({
32
+ file_path: "/something_spec.rb",
33
+ line_number: 15,
34
+ full_description: "should do something"
35
+ })
36
+ end
37
+
38
+ def simulate_test_suite_run
39
+ run.start
40
+ run.example_started(double(example: example))
41
+ simulate_query "SELECT * FROM users LIMIT 1;"
42
+ simulate_query "SELECT * FROM comments WHERE user_id = 1;"
43
+ simulate_request
44
+ run.example_passed
45
+ end
46
+
47
+ before do
48
+ stub_const("RspecProfiling::CurrentCommit", commit)
49
+ stub_const("ActiveSupport::Notifications", Notifications.new)
50
+ simulate_test_suite_run
51
+ end
52
+
53
+ it "collects a single example" do
54
+ expect(collector.count).to eq 1
55
+ end
56
+
57
+ it "counts two queries" do
58
+ expect(result.query_count).to eq 2
59
+ end
60
+
61
+ it "counts one request" do
62
+ expect(result.request_count).to eq 1
63
+ end
64
+
65
+ it "records the file" do
66
+ expect(result.file).to eq "/something_spec.rb"
67
+ end
68
+
69
+ it "records the file number" do
70
+ expect(result.line_number).to eq 15
71
+ end
72
+
73
+ it "records the description" do
74
+ expect(result.description).to eq "should do something"
75
+ end
76
+
77
+ it "records the time" do
78
+ expect(result.time).to eq 500
79
+ end
80
+
81
+ it "records the query time" do
82
+ expect(result.query_time).to eq 200
83
+ end
84
+
85
+ it "records the request time" do
86
+ expect(result.request_time).to eq 10
87
+ end
88
+ end
89
+
90
+ class CollectorDouble
91
+ attr_reader :results
92
+
93
+ def initialize
94
+ @results = []
95
+ end
96
+
97
+ def insert(result)
98
+ @results << OpenStruct.new(result)
99
+ end
100
+
101
+ def count
102
+ results.count
103
+ end
104
+ end
105
+
106
+ class ExampleDouble
107
+ attr_reader :metadata
108
+
109
+ def initialize(metadata)
110
+ @metadata = metadata
111
+ end
112
+
113
+ def execution_result
114
+ OpenStruct.new({
115
+ run_time: 500,
116
+ status: :passed
117
+ })
118
+ end
119
+ end
120
+
121
+ class Notifications
122
+ def initialize
123
+ @subscriptions = Hash.new { |h, k| h[k] = [] }
124
+ end
125
+
126
+ def subscribe(event, &block)
127
+ @subscriptions[event].push block
128
+ end
129
+
130
+ def instrument(event, *args)
131
+ @subscriptions[event].each { |callback| callback.call(*args) }
132
+ end
133
+ end
134
+ end
135
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec_profiling
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Eddy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sqlite3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Profile RSpec test suites
84
+ email:
85
+ - bae@foraker.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - lib/rspec_profiling.rb
96
+ - lib/rspec_profiling/collectors/csv.rb
97
+ - lib/rspec_profiling/collectors/database.rb
98
+ - lib/rspec_profiling/config.rb
99
+ - lib/rspec_profiling/console.rb
100
+ - lib/rspec_profiling/current_commit.rb
101
+ - lib/rspec_profiling/example.rb
102
+ - lib/rspec_profiling/rspec.rb
103
+ - lib/rspec_profiling/run.rb
104
+ - lib/rspec_profiling/version.rb
105
+ - lib/tasks/rspec_profiling.rake
106
+ - rspec_profiling
107
+ - rspec_profiling.gemspec
108
+ - spec/collectors/database_spec.rb
109
+ - spec/run_spec.rb
110
+ homepage: https://github.com/foraker/rspec_profiling
111
+ licenses:
112
+ - MIT
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.0.3
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Profile RSpec test suites
134
+ test_files:
135
+ - spec/collectors/database_spec.rb
136
+ - spec/run_spec.rb
137
+ has_rdoc: