timed_specs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in timed_specs.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ VERSION = "0.0.1"
@@ -0,0 +1,75 @@
1
+ require 'rspec/core/formatters/documentation_formatter'
2
+
3
+
4
+ class TimedSpecs < RSpec::Core::Formatters::DocumentationFormatter
5
+ SLOWEST_EXAMPLES_COUNT = (ENV['SLOWEST_EXAMPLES_COUNT'] || 20).to_i
6
+
7
+ def initialize(*args)
8
+ super
9
+ @examples_with_execution_time = []
10
+ end
11
+
12
+ def start(*args)
13
+ @output.puts "Time Specs Enabled"
14
+ super
15
+ end
16
+
17
+ def example_group_started(*args)
18
+ @group_time = Time.now
19
+ super
20
+ end
21
+
22
+ def example_group_finished(*args)
23
+ super
24
+ if @group_time
25
+ output.puts current_indentation + white("#{(Time.now - @group_time).round(3)}s")
26
+ @group_time = nil
27
+ else
28
+ output.puts
29
+ end
30
+ end
31
+
32
+ # Overridden method of the base documentation formatter
33
+ # Is executed after each passed example
34
+ def example_passed(example)
35
+ super(example)
36
+ @examples_with_execution_time << [
37
+ example.description,
38
+ example.metadata[:execution_result][:run_time], # this is the time taken to execute the example
39
+ format_caller(example.location) # relative path to the example file
40
+ ]
41
+ end
42
+
43
+ # Overridden method of the base documentation formatter
44
+ # Used by DocumentationFormatter to display the example info after each passed example
45
+ # super - displays the example description
46
+ # Then display the execution time beside it
47
+ def passed_output(example)
48
+ super + cyan(" : #{example.metadata[:execution_result][:run_time].round(3)}s")
49
+ end
50
+
51
+ def start_dump
52
+ output_slowest_examples unless @examples_with_execution_time.empty?
53
+ super
54
+ end
55
+
56
+ private
57
+
58
+ def output_slowest_examples
59
+ output.puts bold("\n\nSlowest examples:\n")
60
+
61
+ sort_by_run_time(@examples_with_execution_time)[0..SLOWEST_EXAMPLES_COUNT-1].each do |example|
62
+ output_slow_example(example)
63
+ end
64
+ end
65
+
66
+ def output_slow_example(example)
67
+ output.puts "#{bold(example[1].round(4))} #{example[0]}"
68
+ output.puts " " + cyan("# #{example[2]}")
69
+ end
70
+
71
+ def sort_by_run_time(examples)
72
+ # example[1] = example_run_time
73
+ examples.sort{|x,y| y[1] <=> x[1] }
74
+ end
75
+ end
@@ -0,0 +1,33 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'pry'
4
+ require 'timed_specs'
5
+
6
+ # To properly reset the value of constants
7
+ # Extracted from: http://digitaldumptruck.jotabout.com/?p=551
8
+ def with_constants(constants)
9
+ saved_constants = {}
10
+
11
+ begin
12
+ constants.each do |constant, val|
13
+ saved_constants[constant] = TimedSpecs.const_get( constant )
14
+ without_warnings { TimedSpecs.const_set(constant, val) }
15
+ end
16
+ yield
17
+ ensure
18
+ saved_constants.each do |constant, val|
19
+ without_warnings { TimedSpecs.const_set(constant, val) }
20
+ end
21
+ end
22
+ end
23
+
24
+ # Assigning a value to a constant generates a warning which is supressed by this method
25
+ def without_warnings
26
+ original_verbosity = $VERBOSE
27
+ begin
28
+ $VERBOSE = nil
29
+ yield
30
+ ensure
31
+ $VERBOSE = original_verbosity
32
+ end
33
+ end
@@ -0,0 +1,201 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimedSpecs do
4
+
5
+ let(:output) { StringIO.new }
6
+ let(:formatter) { TimedSpecs.new(output) }
7
+ let(:example_group){ RSpec::Core::ExampleGroup.describe("dummy example group") }
8
+
9
+ context "when initialized" do
10
+ describe "@examples_with_execution_time" do
11
+ it "should be initialized" do
12
+ formatter.instance_variables.should include(:@examples_with_execution_time)
13
+ end
14
+ it "should be an empty array" do
15
+ formatter.instance_variable_get("@examples_with_execution_time").should eq([])
16
+ end
17
+ end
18
+ end
19
+
20
+ describe "#start" do
21
+ context "output" do
22
+ before do
23
+ formatter.start(0)
24
+ end
25
+ specify{ formatter.output.string.should include("Time Specs Enabled") }
26
+ end
27
+ end
28
+
29
+ describe "#example_group_started" do
30
+ before do
31
+ @current_time = Time.now + 50
32
+ Time.stub(:now).and_return(@current_time)
33
+ formatter.example_group_started(example_group)
34
+ end
35
+
36
+ it "should initialize @group_time" do
37
+ formatter.instance_variables.should include(:@group_time)
38
+ end
39
+
40
+ it "should set @group_time to the current time" do
41
+ formatter.instance_variable_get("@group_time").should eq(@current_time)
42
+ end
43
+
44
+ end
45
+
46
+ describe "#example_group_finished" do
47
+ context "when @group_time is set" do
48
+ before do
49
+ @time1 = Time.now
50
+ @time2 = Time.now + 10
51
+ Time.stub(:now).and_return(@time2)
52
+ formatter.stub(:current_indentation).and_return("###")
53
+ formatter.instance_variable_set("@group_time", @time1)
54
+ formatter.example_group_finished(example_group)
55
+ end
56
+
57
+ it "should reset @group_time" do
58
+ formatter.instance_variable_get("@group_time").should be_nil
59
+ end
60
+
61
+ context "output" do
62
+ subject{ formatter.output.string }
63
+ it "should include the group time" do
64
+ subject.should include((@time2 - @time1).round(3).to_s)
65
+ end
66
+
67
+ it "should include the current indentation" do
68
+ subject.should include("###")
69
+ end
70
+ end
71
+ end
72
+
73
+ context "when @group_time is not set" do
74
+ specify{ expect{formatter.example_group_finished(example_group)}.to_not raise_error }
75
+ context "output" do
76
+ before do
77
+ formatter.example_group_finished(example_group)
78
+ end
79
+ subject{ formatter.output.string }
80
+ it{ should include("\n") }
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#example_passed" do
86
+ let(:example){
87
+ double(
88
+ "dummy example",
89
+ :description => "my dummy example",
90
+ :metadata => {
91
+ :execution_result => {:status => 'passed', :exception => Exception.new , :run_time => 1.1234}
92
+ },
93
+ :location => "location_to_the_example"
94
+ )
95
+ }
96
+
97
+ before do
98
+ formatter.stub(:format_caller).with("location_to_the_example").and_return("formatted_location_to_the_example")
99
+ formatter.example_passed(example)
100
+ end
101
+
102
+ it "should store the example in @examples_with_execution_time" do
103
+ formatter.instance_variable_get("@examples_with_execution_time").length.should eq(1)
104
+ end
105
+
106
+ context "the stored example" do
107
+ subject{ formatter.instance_variable_get("@examples_with_execution_time").first }
108
+
109
+ it{ should be_an(Array) }
110
+
111
+ it "should contain the description" do
112
+ subject[0].should eq("my dummy example")
113
+ end
114
+
115
+ it "should contain the execution time" do
116
+ subject[1].should eq(1.1234)
117
+ end
118
+
119
+ it "should contain the formatted location" do
120
+ subject[2].should eq("formatted_location_to_the_example")
121
+ end
122
+ end
123
+
124
+ context "output" do
125
+ subject{ formatter.output.string }
126
+
127
+ it{ should include(formatter.send(:cyan," : 1.123s")) }
128
+ end
129
+ end
130
+
131
+ describe "#start_dump" do
132
+ context "when there are no examples" do
133
+ it "should not attempt to display the slowest examples" do
134
+ formatter.should_receive(:output_slowest_examples).exactly(0).times
135
+ formatter.start_dump
136
+ end
137
+ end
138
+ context "when there are some examples" do
139
+ it "should display the slowest examples" do
140
+ formatter.instance_variable_set("@examples_with_execution_time", [1])
141
+ formatter.should_receive(:output_slowest_examples).once.and_return(true)
142
+ formatter.start_dump
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#output_slowest_examples" do
148
+ let(:examples_with_execution_time){
149
+ 5.times.map{|x| ["example#{x}", rand(1000)/rand(1000).to_f, "location_to_example#{x}"] }
150
+ }
151
+ before do
152
+ formatter.instance_variable_set("@examples_with_execution_time", examples_with_execution_time)
153
+ end
154
+ context "output" do
155
+ it "should contain the slowest examples heading" do
156
+ formatter.send("output_slowest_examples")
157
+ formatter.output.string.should include("Slowest examples:")
158
+ end
159
+ end
160
+ context "when the SLOWEST_EXAMPLES_COUNT is greater than the examples count" do
161
+ it "should show the times for all the examples" do
162
+ formatter.should_receive(:output_slow_example).exactly(5).times.and_return(true)
163
+ formatter.send("output_slowest_examples")
164
+ end
165
+ end
166
+
167
+ context "when the SLOWEST_EXAMPLES_COUNT is less than the examples count" do
168
+ it "should only show the SLOWEST_EXAMPLES_COUNT number of examples" do
169
+ formatter.should_receive(:output_slow_example).exactly(2).times.and_return(true)
170
+ with_constants :SLOWEST_EXAMPLES_COUNT => 2 do
171
+ formatter.send("output_slowest_examples")
172
+ end
173
+ end
174
+ end
175
+ end
176
+
177
+ describe "#output_slow_example" do
178
+ let(:slow_example){ ["example1", 1.23456, "location_to_example1"] }
179
+ before do
180
+ formatter.send("output_slow_example", slow_example)
181
+ end
182
+ context "output" do
183
+ subject{ formatter.output.string }
184
+
185
+ it{ should include("example1"), "should include the example description" }
186
+ it{ should include(formatter.send(:bold, "1.2346")), "should include the example time" }
187
+ it{ should include(formatter.send(:cyan, "# location_to_example1")), "should include the example location" }
188
+ end
189
+ end
190
+
191
+ describe "#sort_by_run_time" do
192
+ it "should sort the items in descending order of the second element in the array" do
193
+ examples = 5.times.map{ [nil, rand(100), nil] }
194
+ sorted_examples = formatter.send("sort_by_run_time", examples)
195
+
196
+ sorted_examples[0..-2].each_index do |index|
197
+ sorted_examples[index][1].should be > sorted_examples[index + 1][1]
198
+ end
199
+ end
200
+ end
201
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/timed_specs/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["dipil-saud"]
6
+ gem.email = ["dipil.saud@gmail.com"]
7
+ gem.description = %q{
8
+ A Rspec formatter built upon the default DocumentationFormatter which shows the time taken for each example along with the other information shown by the DocumentationFormatter. You also have the option to list the slowest 'n' examples at the end.
9
+ }
10
+ gem.summary = %q{A rspec formatter which displays the individual time taken by each example and lists the slowest examples. }
11
+ gem.homepage = ""
12
+
13
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ gem.name = "timed_specs"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = VERSION
19
+
20
+ gem.add_runtime_dependency "rspec"
21
+ gem.add_development_dependency "pry"
22
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timed_specs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - dipil-saud
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &2165151740 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2165151740
25
+ - !ruby/object:Gem::Dependency
26
+ name: pry
27
+ requirement: &2165151040 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2165151040
36
+ description: ! "\n A Rspec formatter built upon the default DocumentationFormatter
37
+ which shows the time taken for each example along with the other information shown
38
+ by the DocumentationFormatter. You also have the option to list the slowest 'n'
39
+ examples at the end.\n "
40
+ email:
41
+ - dipil.saud@gmail.com
42
+ executables: []
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - .gitignore
47
+ - Gemfile
48
+ - Rakefile
49
+ - lib/timed_specs.rb
50
+ - lib/timed_specs/version.rb
51
+ - spec/spec_helper.rb
52
+ - spec/time_specs_spec.rb
53
+ - timed_specs.gemspec
54
+ homepage: ''
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 1.8.10
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: A rspec formatter which displays the individual time taken by each example
78
+ and lists the slowest examples.
79
+ test_files:
80
+ - spec/spec_helper.rb
81
+ - spec/time_specs_spec.rb
82
+ has_rdoc: