elapse 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.
@@ -0,0 +1,12 @@
1
+ # General Ruby.
2
+ /.bundle
3
+ .ref-*
4
+ .old*
5
+ *-old*
6
+ /.rvmrc
7
+
8
+ # Project-specific.
9
+ /*.rb
10
+ /doc/
11
+ /pkg/
12
+ /.yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ -fn # Tree-like progress.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem dependencies in `PROJECT.gemspec`.
4
+ gemspec
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ elapse (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rspec (2.8.0)
11
+ rspec-core (~> 2.8.0)
12
+ rspec-expectations (~> 2.8.0)
13
+ rspec-mocks (~> 2.8.0)
14
+ rspec-core (2.8.0)
15
+ rspec-expectations (2.8.0)
16
+ diff-lcs (~> 1.1.2)
17
+ rspec-mocks (2.8.0)
18
+ yard (0.7.5)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ elapse!
25
+ rspec
26
+ yard
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Alex Fortuna
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,119 @@
1
+
2
+ Elapsed time measurement tool
3
+ =============================
4
+
5
+ Introduction
6
+ ------------
7
+
8
+ `Elapse` is a simple tool to measure time taken by various parts of your program.
9
+
10
+
11
+ Setup
12
+ -----
13
+
14
+ ~~~
15
+ $ gem install elapse
16
+ ~~~
17
+
18
+ , or via Bundler's `Gemfile`:
19
+
20
+ ~~~
21
+ gem "elapse"
22
+ #gem "elapse", :git => "git://github.com/dadooda/elapse.git" # Edge version.
23
+ ~~~
24
+
25
+
26
+ Usage
27
+ -----
28
+
29
+ The most common use is the "stacked" (or "unnamed") mode. In stacked mode you invoke `Elapse.start` and `Elapse.took` without arguments:
30
+
31
+ ~~~
32
+ puts "Fetching page (url:'#{url}')"; Elapse.start
33
+ content = open(url).read
34
+ puts "Fetching page ok (took:%.2fs)" % Elapse.took
35
+ ~~~
36
+
37
+ In stacked mode time is **pushed to the stack** on `Elapse.start` and **popped from the stack** on `Elapse.took`/`Elapse.stop`. Thus you can nest unnamed measurements as deep as you like:
38
+
39
+ ~~~
40
+ puts "Processing"; Elapse.start
41
+ puts "Loading data"; Elapse.start
42
+ load_data
43
+ puts "Loading data ok (took:%.2fs)" % Elapse.took
44
+
45
+ puts "Converting data"; Elapse.start
46
+ process_data
47
+ puts "Converting data ok (took:%.2fs)" % Elapse.took
48
+ puts "Processing ok (took:%.2fs)" % Elapse.took
49
+
50
+ # Output:
51
+
52
+ Processing
53
+ Loading data
54
+ Loading data ok (took:2.00s)
55
+ Converting data
56
+ Converting data ok (took:3.00s)
57
+ Processing ok (took:5.00s)
58
+ ~~~
59
+
60
+ "Named" mode. See the stopwatch name argument to `Elapse.start`, `Elapse.stop` and `Elapse.took`:
61
+
62
+ ~~~
63
+ Elapse.start(:load_data)
64
+ load_data
65
+ Elapse.stop(:load_data)
66
+
67
+ Elapse.start(:process_data)
68
+ process_data
69
+ Elapse.stop(:process_data)
70
+
71
+ puts "Time took:"
72
+ [:load_data, :process_data].each do |stopwatch|
73
+ puts "* #{stopwatch}: %.2fs" % Elapse.took(stopwatch)
74
+ end
75
+
76
+ # Output:
77
+
78
+ Time took:
79
+ * load_data: 2.00s
80
+ * process_data: 3.00s
81
+ ~~~
82
+
83
+ In named mode you cat get **cumulative time** measured by the stopwatch:
84
+
85
+ ~~~
86
+ filenames.each do |fn|
87
+ puts "Processing file (fn:'#{fn}')"; Elapse.start(:process_file)
88
+ process_file(fn)
89
+ puts "Processing file ok (took:%.2fs)" % Elapse.took(:process_file)
90
+ end
91
+
92
+ puts "Total file processing took %.2fs" % Elapse.cumulative(:process_file)
93
+ ~~~
94
+
95
+ That's it for the basic intro. See the full [RDoc documentation](http://rubydoc.info/github/dadooda/elapse/master/frames) for more details.
96
+
97
+
98
+ Compatibility
99
+ -------------
100
+
101
+ Tested to run on:
102
+
103
+ * Ruby 1.9.2-p180, Linux, RVM
104
+
105
+ Compatibility issue reports will be greatly appreciated.
106
+
107
+
108
+ Copyright
109
+ ---------
110
+
111
+ Copyright © 2012 Alex Fortuna.
112
+
113
+ Licensed under the MIT License.
114
+
115
+
116
+ Feedback
117
+ --------
118
+
119
+ Send bug reports, suggestions and criticisms through [project's page on GitHub](http://github.com/dadooda/elapse).
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run all specs"
5
+ RSpec::Core::RakeTask.new do |t|
6
+ #t.pattern = "./spec/**/*_spec.rb" # Should be the default pattern.
7
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path("../lib/elapse/version", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "elapse"
5
+ s.version = Elapse::VERSION
6
+ s.authors = ["Alex Fortuna"]
7
+ s.email = ["alex.r@askit.org"]
8
+ s.homepage = "http://github.com/dadooda/elapse"
9
+
10
+ # Copy these from class's description, adjust markup.
11
+ s.summary = %q{Elapsed time measurement tool}
12
+ s.description = %q{Elapsed time measurement tool}
13
+ # end of s.description=
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map {|f| File.basename(f)}
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency "rspec"
21
+ s.add_development_dependency "yard"
22
+ end
@@ -0,0 +1,88 @@
1
+
2
+ # Load all stuff.
3
+ [
4
+ "elapse/**/*.rb",
5
+ ].each do |fmask|
6
+ Dir[File.expand_path("../#{fmask}", __FILE__)].each do |fn|
7
+ require fn
8
+ end
9
+ end
10
+
11
+ # == Elapsed time measurement tool
12
+ #
13
+ # See {rubydoc documentation}[http://rubydoc.info/github/dadooda/elapse/master/frames] for basic usage examples.
14
+ module Elapse
15
+ # Clear everything.
16
+ def self.clear
17
+ instance.clear
18
+ nil
19
+ end
20
+
21
+ # Return sum of all measurements made by the stopwatch.
22
+ #
23
+ # Elapse.start(:mytime); sleep 0.01; Elapse.stop(:mytime)
24
+ # Elapse.cumulative(:mytime) # => 0.01
25
+ # Elapse.start(:mytime); sleep 0.02; Elapse.stop(:mytime)
26
+ # Elapse.cumulative(:mytime) # => 0.03
27
+ def self.cumulative(sw_key)
28
+ instance.cumulative(sw_key)
29
+ end
30
+
31
+ # Reset the named stopwatch.
32
+ #
33
+ # Elapse.reset(:mytime)
34
+ def self.reset(sw_key)
35
+ instance.reset(sw_key)
36
+ end
37
+
38
+ # Start the stopwatch. Return Time::now.
39
+ #
40
+ # start # Stacked mode.
41
+ # start(:mytime) # Named mode.
42
+ def self.start(sw_key = nil)
43
+ instance.start(sw_key)
44
+ end
45
+
46
+ # Stop the stopwatch. Return Time::now.
47
+ #
48
+ # stop # Stacked mode.
49
+ # stop(:mytime) # Named mode.
50
+ def self.stop(sw_key = nil)
51
+ instance.stop(sw_key)
52
+ end
53
+
54
+ # Return time of the last stopwatch measurement. If the stopwatch is running, stop it.
55
+ #
56
+ # Stacked mode:
57
+ #
58
+ # start
59
+ # sleep 0.01
60
+ # took # => 0.01
61
+ #
62
+ # Named mode:
63
+ #
64
+ # start(:mytime)
65
+ # sleep 0.01
66
+ # took(:mytime) # => 0.01
67
+ #
68
+ # Block execution, stacked mode:
69
+ #
70
+ # took {sleep 0.01} # => 0.01
71
+ #
72
+ # Block execution, named mode:
73
+ #
74
+ # took(:mytime) {sleep 0.01} # => 0.01
75
+ def self.took(sw_key = nil, &block)
76
+ instance.took(sw_key, &block)
77
+ end
78
+
79
+ class << self
80
+ private
81
+
82
+ # Return Elapse::Instance.
83
+ def instance
84
+ # We need not publish the instance object. Everything should be made via the API methods.
85
+ @instance ||= Instance.new
86
+ end
87
+ end # class << self
88
+ end
@@ -0,0 +1,112 @@
1
+ module Elapse
2
+ # An instance of the system.
3
+ class Instance
4
+ # Stacked stopwatches.
5
+ attr_accessor :stack
6
+
7
+ # Named stopwatches.
8
+ attr_accessor :stopwatches
9
+
10
+ def initialize(attrs = {})
11
+ clear
12
+ attrs.each {|k, v| send("#{k}=", v)}
13
+ end
14
+
15
+ # Clear everything.
16
+ def clear
17
+ @stack = []
18
+ @stopwatches = {}
19
+ self # By convention.
20
+ end
21
+
22
+ # Return sum of all measurements made by the stopwatch.
23
+ #
24
+ # See Elapse::cumulative.
25
+ def cumulative(sw_key)
26
+ sw = find_stopwatch(sw_key)
27
+
28
+ begin
29
+ sw.cumulative
30
+ rescue RuntimeError => e
31
+ # Append stopwatch name.
32
+ raise "#{e.message}: #{sw_key.inspect}"
33
+ end
34
+ end
35
+
36
+ # Reset the named stopwatch.
37
+ #
38
+ # See Elapse::reset.
39
+ def reset(sw_key)
40
+ # Let's be strict.
41
+ find_stopwatch(sw_key).reset
42
+ end
43
+
44
+ # Start the stopwatch. Return Time::now.
45
+ #
46
+ # See Elapse::start.
47
+ def start(sw_key = nil)
48
+ sw = if sw_key
49
+ # Named mode.
50
+ @stopwatches[sw_key] ||= Stopwatch.new
51
+ else
52
+ # Stacked mode.
53
+ Stopwatch.new
54
+ end
55
+
56
+ begin
57
+ out = sw.start
58
+ rescue RuntimeError => e
59
+ # Append stopwatch name.
60
+ raise "#{e.message}: #{sw_key.inspect}"
61
+ end
62
+
63
+ if not sw_key
64
+ # Stacked mode.
65
+ @stack.push(sw)
66
+ end
67
+
68
+ out
69
+ end
70
+
71
+ # Stop the stopwatch. Return Time::now.
72
+ #
73
+ # See Elapse::stop.
74
+ def stop(sw_key = nil)
75
+ fetch_stopwatch(sw_key).stop
76
+ end
77
+
78
+ # Return time of the last stopwatch measurement. If the stopwatch is running, stop it.
79
+ #
80
+ # See Elapse::took.
81
+ def took(sw_key = nil, &block)
82
+ if block
83
+ start(sw_key)
84
+ yield
85
+ return took(sw_key)
86
+ end
87
+
88
+ fetch_stopwatch(sw_key).took
89
+ end
90
+
91
+ private
92
+
93
+ # Find or pop stopwatch for the given <tt>sw_key</tt>.
94
+ def fetch_stopwatch(sw_key)
95
+ if sw_key
96
+ # Named mode.
97
+ find_stopwatch(sw_key)
98
+ else
99
+ # Stacked mode.
100
+ @stack.pop or raise "Stopwatch stack underflow (you called `stop` more times than `start`)"
101
+ end
102
+ end
103
+
104
+ def find_stopwatch(sw_key)
105
+ # NOTES:
106
+ #
107
+ # * Message looks okay.
108
+ # * Error is actually more `RuntimeError` than `ArgumentError`.
109
+ @stopwatches[sw_key] or raise "Stopwatch not found: #{sw_key.inspect}"
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,68 @@
1
+ module Elapse
2
+ # Our stopwatch class.
3
+ class Stopwatch
4
+ attr_reader :started_at
5
+
6
+ def initialize
7
+ clear
8
+ end
9
+
10
+ # Clear object.
11
+ def clear
12
+ @cumulative = nil
13
+ @started_at = nil
14
+ @took = nil
15
+ self # By convention.
16
+ end
17
+
18
+ # Stop the stopwatch and return cumulative time.
19
+ def cumulative
20
+ stop
21
+ @cumulative
22
+ end
23
+
24
+ # Reset stopwatch.
25
+ def reset
26
+ clear
27
+ nil
28
+ end
29
+
30
+ # Return true if the stopwatch is running.
31
+ def running?
32
+ !!@started_at
33
+ end
34
+
35
+ # Start the stopwatch. Return Time::now.
36
+ def start
37
+ raise "Stopwatch already started" if @started_at
38
+ @started_at = Time.now
39
+ end
40
+
41
+ # Stop the stopwatch. Return Time::now.
42
+ def stop
43
+ now = Time.now
44
+
45
+ # We can stop multiple times. We cannot stop if never started.
46
+ if @started_at
47
+ @cumulative ||= 0.0
48
+ @took = now - @started_at
49
+ @cumulative += @took
50
+ @started_at = nil
51
+ elsif not @cumulative
52
+ raise "Stopwatch was never started"
53
+ end
54
+
55
+ now
56
+ end
57
+
58
+ # Stop the stopwatch and return the last measurement.
59
+ #
60
+ # start
61
+ # sleep 0.1
62
+ # took # => 0.100393978
63
+ def took
64
+ stop
65
+ @took
66
+ end
67
+ end # Stopwatch
68
+ end
@@ -0,0 +1,4 @@
1
+ module Elapse
2
+ # Gem version.
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ describe Elapse::Instance do
4
+ before :each do
5
+ @r = described_class.new
6
+ end
7
+
8
+ # Shared examples.
9
+ it_behaves_like Elapse::Instance
10
+
11
+ describe "#took block mode" do
12
+ it "should work stacked" do
13
+ took = @r.took {sleep 0.01}
14
+ @r.stack.should be_empty
15
+ end
16
+ end
17
+
18
+ describe "stacked mode" do
19
+ describe "#start" do
20
+ it "should add a stopwatch to the stack" do
21
+ @r.stack.size.should == 0
22
+ @r.start
23
+ @r.stack.size.should == 1
24
+ @r.start
25
+ @r.stack.size.should == 2
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ # Custom stuff for this group.
@@ -0,0 +1,104 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ describe Elapse::Stopwatch do
4
+ before :each do
5
+ @r = described_class.new
6
+ end
7
+
8
+ it "should generally work" do
9
+ @r.start
10
+ sleep 0.01
11
+ ("%.2f" % @r.took).should == "0.01"
12
+
13
+ @r.start
14
+ sleep 0.01
15
+ @r.stop
16
+ ("%.2f" % @r.took).should == "0.01"
17
+
18
+ @r.start
19
+ @r.reset
20
+ lambda do
21
+ @r.stop
22
+ end.should raise_error RuntimeError
23
+ end
24
+
25
+ describe "#cumulative" do
26
+ it "should generally work" do
27
+ @r.start; sleep 0.01; @r.stop
28
+ @r.start; sleep 0.02; @r.stop
29
+ ("%.2f" % @r.cumulative).should == "0.03"
30
+ end
31
+
32
+ it "should stop the timer" do
33
+ @r.start
34
+ @r.cumulative
35
+ @r.running?.should == false
36
+ end
37
+
38
+ it "should allow multimple invocations and retain the last value" do
39
+ @r.start
40
+ sleep 0.01
41
+ took1 = @r.cumulative
42
+ sleep 0.02
43
+ took2 = @r.cumulative
44
+ took1.should == took2
45
+ end
46
+ end
47
+
48
+ describe "#start" do
49
+ it "should return a Time object" do
50
+ @r.start.should be_a Time
51
+ end
52
+
53
+ it "should raise if already started" do
54
+ lambda do
55
+ @r.start
56
+ @r.start
57
+ end.should raise_error RuntimeError
58
+ end
59
+ end
60
+
61
+ describe "#stop" do
62
+ it "should return a Time object" do
63
+ @r.start
64
+ @r.stop.should be_a Time
65
+ end
66
+
67
+ it "should raise if never started" do
68
+ lambda do
69
+ @r.stop
70
+ end.should raise_error RuntimeError
71
+ end
72
+
73
+ it "should not raise if called more than once" do
74
+ lambda do
75
+ @r.start
76
+ @r.stop
77
+ @r.stop
78
+ end.should_not raise_error
79
+ end
80
+ end
81
+
82
+ describe "#took" do
83
+ it "should stop the timer" do
84
+ @r.start
85
+ @r.took
86
+ @r.running?.should == false
87
+ end
88
+
89
+ it "should allow multimple invocations and retain the last value" do
90
+ @r.start
91
+ sleep 0.01
92
+ took1 = @r.took
93
+ sleep 0.01
94
+ took2 = @r.took
95
+ took1.should == took2
96
+ end
97
+
98
+ it "should raise if never started" do
99
+ lambda do
100
+ @r.took
101
+ end.should raise_error RuntimeError
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ describe Elapse do
4
+ before :each do
5
+ @r = described_class
6
+ @r.instance_eval {@instance = nil}
7
+ end
8
+
9
+ # Shared examples.
10
+ it_behaves_like Elapse::Instance
11
+
12
+ it "should generally work" do
13
+ end
14
+ end
@@ -0,0 +1,169 @@
1
+ shared_examples_for Elapse::Instance do
2
+ describe "#took block mode" do
3
+ it "should work stacked" do
4
+ took = @r.took {sleep 0.01}
5
+ ("%.2f" % took).should == "0.01"
6
+
7
+ took = @r.took {sleep 0.01; @r.took {sleep 0.02}}
8
+ ("%.2f" % took).should == "0.03"
9
+ end
10
+
11
+ it "should work named" do
12
+ @r.took(:mytime) {sleep 0.01}
13
+ ("%.2f" % @r.took(:mytime)).should == "0.01"
14
+ @r.took(:mytime) {sleep 0.02}
15
+ ("%.2f" % @r.took(:mytime)).should == "0.02"
16
+ ("%.2f" % @r.cumulative(:mytime)).should == "0.03"
17
+ end
18
+ end
19
+
20
+ describe "named mode" do
21
+ it "should generally work" do
22
+ @r.start(:mytime)
23
+ sleep 0.01
24
+ ("%.2f" % @r.took(:mytime)).should == "0.01"
25
+
26
+ # Overlapping stopwatches.
27
+ @r.start(:sw1)
28
+ sleep 0.01
29
+ @r.start(:sw2)
30
+ sleep 0.02
31
+ ("%.2f" % @r.took(:sw1)).should == "0.03"
32
+ ("%.2f" % @r.took(:sw2)).should == "0.02"
33
+ end
34
+
35
+ describe "#cumulative" do
36
+ it "should generally work" do
37
+ @r.start(:mytime); sleep 0.01; @r.stop(:mytime)
38
+ @r.took(:mytime) {sleep 0.02}
39
+ ("%.2f" % @r.cumulative(:mytime)).should == "0.03"
40
+
41
+ @r.reset(:mytime)
42
+ lambda do
43
+ @r.cumulative(:mytime)
44
+ end.should raise_error RuntimeError # "Stopwatch was never started"
45
+
46
+ message = @r.cumulative(:mytime) rescue $!.message
47
+ message.should be_a String
48
+ message.should match /\s*:mytime\s*/
49
+ end
50
+
51
+ it "should validate presence" do
52
+ lambda do
53
+ @r.cumulative(:mytime)
54
+ end.should raise_error RuntimeError
55
+ end
56
+
57
+ it "should report name in exception message" do
58
+ message = @r.cumulative(:mytime) rescue $!.message
59
+ message.should be_a String
60
+ message.should match /\s*:mytime\s*/
61
+ end
62
+ end
63
+
64
+ describe "#reset" do
65
+ it "should validate presence" do
66
+ lambda do
67
+ @r.reset(:mytime)
68
+ end.should raise_error RuntimeError
69
+ end
70
+
71
+ it "should report name in exception message" do
72
+ message = @r.reset(:mytime) rescue $!.message
73
+ message.should be_a String
74
+ message.should match /\s*:mytime\s*/
75
+ end
76
+ end
77
+
78
+ describe "#start" do
79
+ it "should raise if already started" do
80
+ @r.start(:mytime)
81
+ lambda do
82
+ @r.start(:mytime)
83
+ end.should raise_error RuntimeError
84
+ end
85
+
86
+ it "should report name in exception message" do
87
+ @r.start(:mytime)
88
+ message = @r.start(:mytime) rescue $!.message
89
+ message.should be_a String
90
+ message.should match /\s*:mytime\s*/
91
+ end
92
+
93
+ it "should return a Time object" do
94
+ @r.start(:mytime).should be_a Time
95
+ end
96
+ end
97
+
98
+ describe "#stop" do
99
+ it "should return a Time object" do
100
+ @r.start(:mytime)
101
+ @r.stop(:mytime).should be_a Time
102
+ end
103
+
104
+ it "should validate presence" do
105
+ lambda do
106
+ @r.stop(:mytime)
107
+ end.should raise_error RuntimeError
108
+ end
109
+
110
+ it "should report name in exception message" do
111
+ message = @r.stop(:mytime) rescue $!.message
112
+ message.should be_a String
113
+ message.should match /\s*:mytime\s*/
114
+ end
115
+ end
116
+ end # describe "named mode"
117
+
118
+ describe "stacked mode" do
119
+ it "should generally work" do
120
+ @r.start
121
+ sleep 0.01
122
+ ("%.2f" % @r.took).should == "0.01"
123
+
124
+ @r.start
125
+ sleep 0.01
126
+ @r.start
127
+ sleep 0.02
128
+ ("%.2f" % @r.took).should == "0.02"
129
+ ("%.2f" % @r.took).should == "0.03"
130
+ end
131
+
132
+ describe "#start" do
133
+ it "should return a Time object" do
134
+ @r.start.should be_a Time
135
+ end
136
+ end
137
+
138
+ describe "#stop" do
139
+ it "should return a Time object" do
140
+ @r.start
141
+ @r.stop.should be_a Time
142
+ end
143
+
144
+ it "should raise if stack underflow" do
145
+ lambda do
146
+ @r.stop
147
+ end.should raise_error RuntimeError
148
+
149
+ lambda do
150
+ 2.times {@r.start}
151
+ 3.times {@r.stop}
152
+ end.should raise_error RuntimeError
153
+ end
154
+ end
155
+
156
+ describe "#took" do
157
+ it "should raise if stack underflow" do
158
+ lambda do
159
+ @r.took
160
+ end.should raise_error RuntimeError
161
+
162
+ lambda do
163
+ 2.times {@r.start}
164
+ 3.times {@r.took}
165
+ end.should raise_error RuntimeError
166
+ end
167
+ end
168
+ end # describe "stacked mode"
169
+ end # shared_examples_for Elapse::Instance
@@ -0,0 +1,30 @@
1
+ # NOTE: I usually support `STANDALONE` mode in specs for Rails projects' components
2
+ # to be able to test them without loading the environment. This project does not
3
+ # depend on Rails *BUT* I still want a consistent RSpec file structure.
4
+ # If this is confusing, feel free to propose something better. :)
5
+
6
+ # No Rails, we're always standalone... and free! :)
7
+ STANDALONE = 1
8
+
9
+ if STANDALONE
10
+ # Provide root path object.
11
+ module Standalone
12
+ eval <<-EOT
13
+ def self.root
14
+ # This is an absolute path, it's perfectly safe to do a `+` and then `require`.
15
+ Pathname("#{File.expand_path('../..', __FILE__)}")
16
+ end
17
+ EOT
18
+ end
19
+
20
+ # Load stuff.
21
+ [
22
+ "lib/**/*.rb",
23
+ ].each do |fmask|
24
+ Dir[Standalone.root + fmask].each do |fn|
25
+ require fn
26
+ end
27
+ end
28
+ end
29
+
30
+ require File.expand_path("../shared_examples", __FILE__)
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elapse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Fortuna
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-12 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &81559990 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *81559990
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ requirement: &81559720 !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: *81559720
36
+ description: Elapsed time measurement tool
37
+ email:
38
+ - alex.r@askit.org
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - .rspec
45
+ - Gemfile
46
+ - Gemfile.lock
47
+ - MIT-LICENSE
48
+ - README.md
49
+ - Rakefile
50
+ - elapse.gemspec
51
+ - lib/elapse.rb
52
+ - lib/elapse/instance.rb
53
+ - lib/elapse/stopwatch.rb
54
+ - lib/elapse/version.rb
55
+ - spec/elapse/instance_spec.rb
56
+ - spec/elapse/spec_helper.rb
57
+ - spec/elapse/stopwatch_spec.rb
58
+ - spec/elapse_spec.rb
59
+ - spec/shared_examples.rb
60
+ - spec/spec_helper.rb
61
+ homepage: http://github.com/dadooda/elapse
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.10
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Elapsed time measurement tool
85
+ test_files: []
86
+ has_rdoc: