watchme 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.
- data/.gitignore +12 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +64 -0
- data/Rakefile +13 -0
- data/autotest/discover.rb +1 -0
- data/lib/watchme.rb +8 -0
- data/lib/watchme/ci.rake +56 -0
- data/lib/watchme/timer.rb +114 -0
- data/lib/watchme/version.rb +3 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/timer_spec.rb +318 -0
- data/watchme.gemspec +28 -0
- metadata +147 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
watchme (0.0.1)
|
|
5
|
+
activesupport (>= 3.0.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: http://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
ZenTest (4.7.0)
|
|
11
|
+
activesupport (3.2.3)
|
|
12
|
+
i18n (~> 0.6)
|
|
13
|
+
multi_json (~> 1.0)
|
|
14
|
+
autotest-fsevent (0.2.8)
|
|
15
|
+
sys-uname
|
|
16
|
+
builder (3.0.0)
|
|
17
|
+
diff-lcs (1.1.3)
|
|
18
|
+
ffi (1.0.11)
|
|
19
|
+
geminabox (0.6.1)
|
|
20
|
+
builder
|
|
21
|
+
httpclient
|
|
22
|
+
sinatra
|
|
23
|
+
guard (1.0.1)
|
|
24
|
+
ffi (>= 0.5.0)
|
|
25
|
+
thor (~> 0.14.6)
|
|
26
|
+
guard-rspec (0.7.0)
|
|
27
|
+
guard (>= 0.10.0)
|
|
28
|
+
httpclient (2.2.4)
|
|
29
|
+
i18n (0.6.0)
|
|
30
|
+
multi_json (1.3.2)
|
|
31
|
+
rack (1.4.1)
|
|
32
|
+
rack-protection (1.2.0)
|
|
33
|
+
rack
|
|
34
|
+
rake (0.9.2.2)
|
|
35
|
+
rb-fsevent (0.9.1)
|
|
36
|
+
rspec (2.9.0)
|
|
37
|
+
rspec-core (~> 2.9.0)
|
|
38
|
+
rspec-expectations (~> 2.9.0)
|
|
39
|
+
rspec-mocks (~> 2.9.0)
|
|
40
|
+
rspec-core (2.9.0)
|
|
41
|
+
rspec-expectations (2.9.1)
|
|
42
|
+
diff-lcs (~> 1.1.3)
|
|
43
|
+
rspec-mocks (2.9.0)
|
|
44
|
+
sinatra (1.3.2)
|
|
45
|
+
rack (~> 1.3, >= 1.3.6)
|
|
46
|
+
rack-protection (~> 1.2)
|
|
47
|
+
tilt (~> 1.3, >= 1.3.3)
|
|
48
|
+
sys-uname (0.9.0)
|
|
49
|
+
ffi (>= 1.0.0)
|
|
50
|
+
thor (0.14.6)
|
|
51
|
+
tilt (1.3.3)
|
|
52
|
+
|
|
53
|
+
PLATFORMS
|
|
54
|
+
ruby
|
|
55
|
+
|
|
56
|
+
DEPENDENCIES
|
|
57
|
+
ZenTest
|
|
58
|
+
autotest-fsevent
|
|
59
|
+
geminabox
|
|
60
|
+
guard-rspec
|
|
61
|
+
rake
|
|
62
|
+
rb-fsevent
|
|
63
|
+
rspec
|
|
64
|
+
watchme!
|
data/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
2
|
+
require 'rspec/core/rake_task'
|
|
3
|
+
|
|
4
|
+
if ENV['RAILS_BUNDLE_FIRST']
|
|
5
|
+
unless system('bundle check')
|
|
6
|
+
# system('ruby -r rubygems -e "p Gem.path"')
|
|
7
|
+
puts "RAILS_BUNDLE_FIRST is set, running `bundle install`..."
|
|
8
|
+
system("bundle install") || raise("'bundle install' failed.")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
import 'lib/watchme/ci.rake'
|
|
13
|
+
RSpec::Core::RakeTask.new
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/lib/watchme.rb
ADDED
data/lib/watchme/ci.rake
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
|
|
2
|
+
namespace :ci do
|
|
3
|
+
desc "Perform a build on the CI server"
|
|
4
|
+
task :build do
|
|
5
|
+
begin
|
|
6
|
+
Rake::Task['ci:qa'].invoke
|
|
7
|
+
Rake::Task['ci:success'].invoke
|
|
8
|
+
rescue Exception => e
|
|
9
|
+
Rake::Task['ci:failure'].invoke
|
|
10
|
+
raise e
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
desc "Update your code base (will erase local changes!!!)"
|
|
15
|
+
task :rebase do
|
|
16
|
+
system('git checkout .')
|
|
17
|
+
system('git pull --rebase')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc "Run QA"
|
|
21
|
+
task :qa do
|
|
22
|
+
Rake::Task['ci:rspec'].invoke
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc "Run Rspec"
|
|
26
|
+
task :rspec do
|
|
27
|
+
system "mkdir -p ../public" unless File.exists?("../public")
|
|
28
|
+
Rake::Task['ci:rspec_run'].invoke
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
RSpec::Core::RakeTask.new(:rspec_run) do |t|
|
|
32
|
+
t.pattern = "./spec/**/*spec.rb"
|
|
33
|
+
t.rspec_opts = ["--format", "html", "--out", "../public/rspec.html"]
|
|
34
|
+
t.fail_on_error = true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
desc "The Build Succeeded, so tell our monitoring service"
|
|
38
|
+
task :success do
|
|
39
|
+
if File.exists?("/home/deployer/monitor/log")
|
|
40
|
+
system 'echo "WatchMe succeeded, http://cc.cenx.localnet" > /home/deployer/monitor/log/WatchMe.cc'
|
|
41
|
+
else
|
|
42
|
+
print "BUILD SUCCEEDED, but log directory (/home/deployer/monitor/log) does not exist"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc "The Build failed, so tell our monitoring service"
|
|
47
|
+
task :failure do
|
|
48
|
+
if File.exists?("/home/deployer/monitor/log")
|
|
49
|
+
system "curl http://cc.cenx.localnet/watchme > /home/deployer/monitor/log/WatchMe.cc"
|
|
50
|
+
else
|
|
51
|
+
raise "BUILD FAILED, but log directory (/home/deployer/monitor/log) does not exist"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
|
|
2
|
+
module WatchMe
|
|
3
|
+
class Timer
|
|
4
|
+
|
|
5
|
+
attr_accessor :duration, :start_time, :stop_time
|
|
6
|
+
|
|
7
|
+
def initialize(data = {})
|
|
8
|
+
@duration = data[:duration]
|
|
9
|
+
start
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def start
|
|
13
|
+
@start_time = Time.now
|
|
14
|
+
@start_time
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def stop
|
|
18
|
+
@stop_time = Time.now
|
|
19
|
+
update_duration_as_required
|
|
20
|
+
@stop_time
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def duration_to_s
|
|
24
|
+
Timer.calculate_duration_to_s(duration)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.num_increments(inc_duration,total_duration)
|
|
28
|
+
inc_secs = to_seconds(inc_duration)
|
|
29
|
+
total_secs = to_seconds(total_duration)*1.0
|
|
30
|
+
return 0 if inc_secs == 0
|
|
31
|
+
return (total_secs / inc_secs).ceil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.to_minutes(input,data = {})
|
|
35
|
+
result, has_scale = to_seconds_or_as_is(input,data)
|
|
36
|
+
result /= 60 if has_scale
|
|
37
|
+
result
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.to_seconds(input,data = {})
|
|
41
|
+
result, has_scale = to_seconds_or_as_is(input,data)
|
|
42
|
+
result
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.calculate_duration_to_s(duration_in_seconds)
|
|
46
|
+
return "N/A" if duration_in_seconds.nil?
|
|
47
|
+
|
|
48
|
+
#TODO use sortable hash if ruby 1.9.2
|
|
49
|
+
times = [ 60*60*24*365.0, 60*60*24.0, 60*60.0, 60.0, 1.0, 0.001]
|
|
50
|
+
names = [ 'year','day','hour','minute','second', 'millisecond']
|
|
51
|
+
|
|
52
|
+
times.each_with_index do |factor,index|
|
|
53
|
+
adjusted_time = duration_in_seconds / factor
|
|
54
|
+
next if (adjusted_time < 1 && factor != 0.001)
|
|
55
|
+
adjusted_time = (adjusted_time * 100).round / 100.0
|
|
56
|
+
adjusted_time = adjusted_time.round if adjusted_time == adjusted_time.round
|
|
57
|
+
name = adjusted_time == 1 ? names[index] : names[index].pluralize
|
|
58
|
+
return "#{adjusted_time} #{name}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def self.to_seconds_or_as_is(input,data = {})
|
|
65
|
+
return [0,false] if input.nil?
|
|
66
|
+
return [input.to_i,false] if input.to_s == input.to_i.to_s
|
|
67
|
+
|
|
68
|
+
days_in_month = data[:days_in_month] || 31
|
|
69
|
+
days_in_year = data[:days_in_year] || 366
|
|
70
|
+
|
|
71
|
+
now = data[:now]
|
|
72
|
+
now = Time.at(data[:now_epoch]) if now.nil? && !data[:now_epoch].nil?
|
|
73
|
+
unless now.nil?
|
|
74
|
+
days_in_month = now.end_of_month.day
|
|
75
|
+
days_in_year = now.end_of_year.yday
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
input = "#{input}"
|
|
79
|
+
input.gsub!(/\s/,"")
|
|
80
|
+
m = input.match(/^(\d*)$/)
|
|
81
|
+
return [ m[1].to_i, false ] unless m.nil?
|
|
82
|
+
m = input.match(/^(\d*)(.*)s$/)
|
|
83
|
+
m = input.match(/^(\d*)(.*)$/) if m.nil?
|
|
84
|
+
return [0, false] if m.nil?
|
|
85
|
+
d = (m[1] == "") ? 1 : m[1].to_i
|
|
86
|
+
scale = m[2]
|
|
87
|
+
answer = case scale
|
|
88
|
+
when "second"
|
|
89
|
+
d
|
|
90
|
+
when "minute"
|
|
91
|
+
d * 60
|
|
92
|
+
when "hour"
|
|
93
|
+
d * 60 * 60
|
|
94
|
+
when "day"
|
|
95
|
+
d * 60 * 60 * 24
|
|
96
|
+
when "week"
|
|
97
|
+
d * 60 * 60 * 24 * 7
|
|
98
|
+
when "month"
|
|
99
|
+
d * 60 * 60 * 24 * days_in_month
|
|
100
|
+
when "year"
|
|
101
|
+
d * 60 * 60 * 24 * days_in_year
|
|
102
|
+
else
|
|
103
|
+
0
|
|
104
|
+
end
|
|
105
|
+
[answer,true]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def update_duration_as_required
|
|
109
|
+
return if @start_time.nil? || @stop_time.nil?
|
|
110
|
+
@duration = @stop_time - @start_time
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
require 'rspec'
|
|
4
|
+
require File.dirname(__FILE__) + '/../lib/watchme'
|
|
5
|
+
|
|
6
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
7
|
+
# in spec/support/ and its subdirectories.
|
|
8
|
+
# Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
|
9
|
+
|
|
10
|
+
RSpec.configure do |config|
|
|
11
|
+
config.mock_with :rspec
|
|
12
|
+
end
|
data/spec/timer_spec.rb
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module WatchMe
|
|
4
|
+
describe Timer do
|
|
5
|
+
|
|
6
|
+
before(:each) do
|
|
7
|
+
@before_now = Time.parse("2010-09-21 10:11:10")
|
|
8
|
+
@now = Time.parse("2010-09-21 10:11:12")
|
|
9
|
+
Time.stub!(:now).and_return(@now)
|
|
10
|
+
@obj = Timer.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "#initialize" do
|
|
14
|
+
|
|
15
|
+
it "should set duration to nil" do
|
|
16
|
+
@obj.duration.should == nil
|
|
17
|
+
@obj.start_time.should == @now
|
|
18
|
+
@obj.stop_time.should == nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should support constructor values" do
|
|
22
|
+
obj = Timer.new(:duration => 12.34)
|
|
23
|
+
obj.duration.should == 12.34
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#start" do
|
|
29
|
+
|
|
30
|
+
it "should set start_time to now" do
|
|
31
|
+
@obj.start.should == @now
|
|
32
|
+
@obj.start_time.should == @now
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "#stop" do
|
|
38
|
+
|
|
39
|
+
it "should set stop_time to now" do
|
|
40
|
+
@obj.stop.should == @now
|
|
41
|
+
@obj.stop_time.should == @now
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should leave duration alone if start time nil" do
|
|
45
|
+
@obj.start_time = nil
|
|
46
|
+
@obj.stop
|
|
47
|
+
@obj.duration.should == nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should update the duration if start time set" do
|
|
51
|
+
Time.stub!(:now).and_return(@before_now)
|
|
52
|
+
@obj.start
|
|
53
|
+
Time.stub!(:now).and_return(@now)
|
|
54
|
+
@obj.stop
|
|
55
|
+
@obj.duration.should == 2
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe "#calculate_duration_to_s" do
|
|
61
|
+
|
|
62
|
+
it "should support nil" do
|
|
63
|
+
Timer.calculate_duration_to_s(nil).should == "N/A"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "only two decimal places" do
|
|
67
|
+
Timer.calculate_duration_to_s(19.342).should == '19.34 seconds'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "milliseconds" do
|
|
71
|
+
Timer.calculate_duration_to_s(0.34).should == '340 milliseconds'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "seconds" do
|
|
75
|
+
Timer.calculate_duration_to_s(9.34).should == '9.34 seconds'
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "minutes" do
|
|
79
|
+
Timer.calculate_duration_to_s(1.12*60).should == '1.12 minutes'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "hours" do
|
|
83
|
+
Timer.calculate_duration_to_s(1.5*60*60).should == '1.5 hours'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "days" do
|
|
87
|
+
Timer.calculate_duration_to_s(2.8*60*60*24).should == '2.8 days'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "years" do
|
|
91
|
+
Timer.calculate_duration_to_s(9.8*60*60*24*365).should == '9.8 years'
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "second" do
|
|
95
|
+
Timer.calculate_duration_to_s(1).should == '1 second'
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "minute" do
|
|
99
|
+
Timer.calculate_duration_to_s(60).should == '1 minute'
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "hour" do
|
|
103
|
+
Timer.calculate_duration_to_s(1*60*60).should == '1 hour'
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "day" do
|
|
107
|
+
Timer.calculate_duration_to_s(1*60*60*24).should == '1 day'
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "year" do
|
|
111
|
+
Timer.calculate_duration_to_s(1*60*60*24*365).should == '1 year'
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
describe "#num_increments" do
|
|
117
|
+
|
|
118
|
+
it "should internally convert the units" do
|
|
119
|
+
Timer.num_increments("30seconds","3minutes").should == 6
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "should round up" do
|
|
123
|
+
Timer.num_increments("45seconds","1minutes").should == 2
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "should handle months to months perfectly" do
|
|
127
|
+
Timer.num_increments("2month","10months").should == 5
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "should handle nil" do
|
|
131
|
+
Timer.num_increments("",nil).should == 0
|
|
132
|
+
Timer.num_increments(nil,"").should == 0
|
|
133
|
+
Timer.num_increments("garble","garble").should == 0
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
describe "#to_minutes" do
|
|
140
|
+
|
|
141
|
+
it "Should just grab the seconds and convert" do
|
|
142
|
+
Timer.to_minutes("30second").should == 0
|
|
143
|
+
Timer.to_minutes("10minutes").should == 10
|
|
144
|
+
Timer.to_minutes("hour").should == 60
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it "should keep as-is in the units as expected" do
|
|
148
|
+
Timer.to_minutes(30).should == 30
|
|
149
|
+
Timer.to_minutes("30").should == 30
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should accept how many days in a month, and year" do
|
|
153
|
+
Timer.to_minutes("month", :days_in_month => 28).should == 60 * 24 * 28
|
|
154
|
+
Timer.to_minutes("month", :days_in_month => 31).should == 60 * 24 * 31
|
|
155
|
+
|
|
156
|
+
Timer.to_minutes("year", :days_in_year => 365).should == 60 * 24 * 365
|
|
157
|
+
Timer.to_minutes("year", :days_in_year => 366).should == 60 * 24 * 366
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
it "should accept how many now for month conversion" do
|
|
161
|
+
Timer.to_minutes("month", :now => Time.parse("2011-09-21")).should == 60 * 24 * 30
|
|
162
|
+
Timer.to_minutes("month", :now_epoch => Time.parse("2011-10-21").to_i).should == 60 * 24 * 31
|
|
163
|
+
|
|
164
|
+
Timer.to_minutes("year", :now => Time.parse("2011-09-21")).should == 60 * 24 * 365
|
|
165
|
+
Timer.to_minutes("year", :now_epoch => Time.parse("2012-09-21").to_i).should == 60 * 24 * 366
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
describe "#to_seconds" do
|
|
172
|
+
|
|
173
|
+
it "should support nil" do
|
|
174
|
+
Timer.to_seconds(nil).should == 0
|
|
175
|
+
Timer.to_seconds("").should == 0
|
|
176
|
+
Timer.to_seconds("garble").should == 0
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "should keep as-is in the units as expected" do
|
|
180
|
+
Timer.to_minutes(30).should == 30
|
|
181
|
+
Timer.to_minutes("30").should == 30
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should support no number" do
|
|
185
|
+
Timer.to_seconds("second").should == 1
|
|
186
|
+
Timer.to_seconds("minute").should == 1 * 60
|
|
187
|
+
Timer.to_seconds("hour").should == 1 * 60 * 60
|
|
188
|
+
Timer.to_seconds("day").should == 1 * 60 * 60 * 24
|
|
189
|
+
Timer.to_seconds("week").should == 1 * 60 * 60 * 24 * 7
|
|
190
|
+
Timer.to_seconds("month").should == 1 * 60 * 60 * 24 * 31
|
|
191
|
+
Timer.to_seconds("year").should == 1 * 60 * 60 * 24 * 366
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it "should support seconds" do
|
|
195
|
+
Timer.to_seconds("10 seconds").should == 10
|
|
196
|
+
Timer.to_seconds("10 second").should == 10
|
|
197
|
+
Timer.to_seconds("10second").should == 10
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "should support minutes" do
|
|
201
|
+
Timer.to_seconds("10 minutes").should == 10*60
|
|
202
|
+
Timer.to_seconds("10 minute").should == 10*60
|
|
203
|
+
Timer.to_seconds("10minute").should == 10*60
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should support hours" do
|
|
207
|
+
Timer.to_seconds("10 hours").should == 10*60*60
|
|
208
|
+
Timer.to_seconds("10 hour").should == 10*60*60
|
|
209
|
+
Timer.to_seconds("10hour").should == 10*60*60
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "should support days" do
|
|
213
|
+
Timer.to_seconds("10 days").should == 10*60*60*24
|
|
214
|
+
Timer.to_seconds("10 day").should == 10*60*60*24
|
|
215
|
+
Timer.to_seconds("10day").should == 10*60*60*24
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "should support weeks" do
|
|
219
|
+
Timer.to_seconds("10 weeks").should == 10*60*60*24*7
|
|
220
|
+
Timer.to_seconds("10 week").should == 10*60*60*24*7
|
|
221
|
+
Timer.to_seconds("10week").should == 10*60*60*24*7
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should support the a 31 day month" do
|
|
225
|
+
Timer.to_seconds("10 months").should == 10*60*60*24*31
|
|
226
|
+
Timer.to_seconds("10 months").should == 10*60*60*24*31
|
|
227
|
+
Timer.to_seconds("10month").should == 10*60*60*24*31
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it "should support a 366 day year" do
|
|
231
|
+
Timer.to_seconds("10 years").should == 10*60*60*24*366
|
|
232
|
+
Timer.to_seconds("10 years").should == 10*60*60*24*366
|
|
233
|
+
Timer.to_seconds("10years").should == 10*60*60*24*366
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "should ignore other times" do
|
|
237
|
+
Timer.to_seconds("10 garbles").should == 0
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "should accept how many days in a month, and year" do
|
|
241
|
+
Timer.to_seconds("month", :days_in_month => 28).should == 60 * 60 * 24 * 28
|
|
242
|
+
Timer.to_seconds("month", :days_in_month => 31).should == 60 * 60 * 24 * 31
|
|
243
|
+
|
|
244
|
+
Timer.to_seconds("year", :days_in_year => 365).should == 60 * 60 * 24 * 365
|
|
245
|
+
Timer.to_seconds("year", :days_in_year => 366).should == 60 * 60 * 24 * 366
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should accept how many now for month conversion" do
|
|
249
|
+
Timer.to_seconds("month", :now => Time.parse("2011-09-21")).should == 60 * 60 * 24 * 30
|
|
250
|
+
Timer.to_seconds("month", :now_epoch => Time.parse("2011-10-21").to_i).should == 60 * 60 * 24 * 31
|
|
251
|
+
|
|
252
|
+
Timer.to_seconds("year", :now => Time.parse("2011-09-21")).should == 60 * 60 * 24 * 365
|
|
253
|
+
Timer.to_seconds("year", :now_epoch => Time.parse("2012-09-21").to_i).should == 60 * 60 * 24 * 366
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
describe "#duration_to_s" do
|
|
260
|
+
|
|
261
|
+
it "should support nil" do
|
|
262
|
+
obj = Timer.new
|
|
263
|
+
obj.duration_to_s.should == "N/A"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it "only two decimal places" do
|
|
267
|
+
Timer.new(:duration => 19.342).duration_to_s.should == '19.34 seconds'
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "milliseconds" do
|
|
271
|
+
Timer.new(:duration => 0.34).duration_to_s.should == '340 milliseconds'
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
it "seconds" do
|
|
275
|
+
Timer.new(:duration => 9.34).duration_to_s.should == '9.34 seconds'
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it "minutes" do
|
|
279
|
+
Timer.new(:duration => 1.12*60).duration_to_s.should == '1.12 minutes'
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "hours" do
|
|
283
|
+
Timer.new(:duration => 1.5*60*60).duration_to_s.should == '1.5 hours'
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
it "days" do
|
|
287
|
+
Timer.new(:duration => 2.8*60*60*24).duration_to_s.should == '2.8 days'
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "years" do
|
|
291
|
+
Timer.new(:duration => 9.8*60*60*24*365).duration_to_s.should == '9.8 years'
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
it "second" do
|
|
295
|
+
Timer.new(:duration => 1).duration_to_s.should == '1 second'
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it "minute" do
|
|
299
|
+
Timer.new(:duration => 60).duration_to_s.should == '1 minute'
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "hour" do
|
|
303
|
+
Timer.new(:duration => 1*60*60).duration_to_s.should == '1 hour'
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
it "day" do
|
|
307
|
+
Timer.new(:duration => 1*60*60*24).duration_to_s.should == '1 day'
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "year" do
|
|
311
|
+
Timer.new(:duration => 1*60*60*24*365).duration_to_s.should == '1 year'
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
data/watchme.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "watchme/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "watchme"
|
|
7
|
+
s.version = WatchMe::VERSION
|
|
8
|
+
s.authors = ["Andrew Forward"]
|
|
9
|
+
s.email = ["aforward@gmail.com"]
|
|
10
|
+
s.homepage = "http://github.com/aforward/watchme"
|
|
11
|
+
s.summary = %q{Simple API for tracking time within a ruby project}
|
|
12
|
+
s.description = %q{Simple API for tracking time within a ruby project}
|
|
13
|
+
|
|
14
|
+
s.files = `git ls-files`.split("\n")
|
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
17
|
+
s.require_paths = ["lib"]
|
|
18
|
+
|
|
19
|
+
s.add_dependency('activesupport','>=3.0.0')
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency('rake')
|
|
22
|
+
s.add_development_dependency('rspec')
|
|
23
|
+
s.add_development_dependency('ZenTest')
|
|
24
|
+
s.add_development_dependency('guard-rspec')
|
|
25
|
+
s.add_development_dependency('autotest-fsevent') if RUBY_PLATFORM =~ /darwin/i
|
|
26
|
+
s.add_development_dependency('rb-fsevent') if RUBY_PLATFORM =~ /darwin/i
|
|
27
|
+
s.add_development_dependency('geminabox')
|
|
28
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: watchme
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Andrew Forward
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-04-25 00:00:00.000000000Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: activesupport
|
|
16
|
+
requirement: &70195297442860 !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 3.0.0
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: *70195297442860
|
|
25
|
+
- !ruby/object:Gem::Dependency
|
|
26
|
+
name: rake
|
|
27
|
+
requirement: &70195297442440 !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: *70195297442440
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: rspec
|
|
38
|
+
requirement: &70195297441980 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ! '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
type: :development
|
|
45
|
+
prerelease: false
|
|
46
|
+
version_requirements: *70195297441980
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: ZenTest
|
|
49
|
+
requirement: &70195297441560 !ruby/object:Gem::Requirement
|
|
50
|
+
none: false
|
|
51
|
+
requirements:
|
|
52
|
+
- - ! '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
type: :development
|
|
56
|
+
prerelease: false
|
|
57
|
+
version_requirements: *70195297441560
|
|
58
|
+
- !ruby/object:Gem::Dependency
|
|
59
|
+
name: guard-rspec
|
|
60
|
+
requirement: &70195297441140 !ruby/object:Gem::Requirement
|
|
61
|
+
none: false
|
|
62
|
+
requirements:
|
|
63
|
+
- - ! '>='
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0'
|
|
66
|
+
type: :development
|
|
67
|
+
prerelease: false
|
|
68
|
+
version_requirements: *70195297441140
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: autotest-fsevent
|
|
71
|
+
requirement: &70195297440620 !ruby/object:Gem::Requirement
|
|
72
|
+
none: false
|
|
73
|
+
requirements:
|
|
74
|
+
- - ! '>='
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
type: :development
|
|
78
|
+
prerelease: false
|
|
79
|
+
version_requirements: *70195297440620
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rb-fsevent
|
|
82
|
+
requirement: &70195297440140 !ruby/object:Gem::Requirement
|
|
83
|
+
none: false
|
|
84
|
+
requirements:
|
|
85
|
+
- - ! '>='
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '0'
|
|
88
|
+
type: :development
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: *70195297440140
|
|
91
|
+
- !ruby/object:Gem::Dependency
|
|
92
|
+
name: geminabox
|
|
93
|
+
requirement: &70195297439600 !ruby/object:Gem::Requirement
|
|
94
|
+
none: false
|
|
95
|
+
requirements:
|
|
96
|
+
- - ! '>='
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
type: :development
|
|
100
|
+
prerelease: false
|
|
101
|
+
version_requirements: *70195297439600
|
|
102
|
+
description: Simple API for tracking time within a ruby project
|
|
103
|
+
email:
|
|
104
|
+
- aforward@gmail.com
|
|
105
|
+
executables: []
|
|
106
|
+
extensions: []
|
|
107
|
+
extra_rdoc_files: []
|
|
108
|
+
files:
|
|
109
|
+
- .gitignore
|
|
110
|
+
- Gemfile
|
|
111
|
+
- Gemfile.lock
|
|
112
|
+
- Rakefile
|
|
113
|
+
- autotest/discover.rb
|
|
114
|
+
- lib/watchme.rb
|
|
115
|
+
- lib/watchme/ci.rake
|
|
116
|
+
- lib/watchme/timer.rb
|
|
117
|
+
- lib/watchme/version.rb
|
|
118
|
+
- spec/spec_helper.rb
|
|
119
|
+
- spec/timer_spec.rb
|
|
120
|
+
- watchme.gemspec
|
|
121
|
+
homepage: http://github.com/aforward/watchme
|
|
122
|
+
licenses: []
|
|
123
|
+
post_install_message:
|
|
124
|
+
rdoc_options: []
|
|
125
|
+
require_paths:
|
|
126
|
+
- lib
|
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
|
+
none: false
|
|
129
|
+
requirements:
|
|
130
|
+
- - ! '>='
|
|
131
|
+
- !ruby/object:Gem::Version
|
|
132
|
+
version: '0'
|
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
|
+
none: false
|
|
135
|
+
requirements:
|
|
136
|
+
- - ! '>='
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
requirements: []
|
|
140
|
+
rubyforge_project:
|
|
141
|
+
rubygems_version: 1.8.10
|
|
142
|
+
signing_key:
|
|
143
|
+
specification_version: 3
|
|
144
|
+
summary: Simple API for tracking time within a ruby project
|
|
145
|
+
test_files:
|
|
146
|
+
- spec/spec_helper.rb
|
|
147
|
+
- spec/timer_spec.rb
|