rduration 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +12 -0
- data/Guardfile +10 -0
- data/LICENSE +22 -0
- data/README.md +95 -0
- data/Rakefile +2 -0
- data/lib/duration/arithmatic.rb +15 -0
- data/lib/duration/string_ext.rb +5 -0
- data/lib/duration/version.rb +3 -0
- data/lib/duration.rb +99 -0
- data/rduration.gemspec +20 -0
- data/spec/duration/string_ext_spec.rb +12 -0
- data/spec/duration_spec.rb +205 -0
- data/spec/spec_helper.rb +11 -0
- metadata +87 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.3@duration_gem
|
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in ruby-duration.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
# Guard & Devtools
|
7
|
+
gem 'guard', '~> 0.8.8'
|
8
|
+
# MacOS notifications:
|
9
|
+
gem 'rb-fsevent', :require => ('rb-fsevent' if RUBY_PLATFORM =~ /darwin/i)
|
10
|
+
gem 'growl', :require => ('growl' if RUBY_PLATFORM =~ /darwin/i)
|
11
|
+
gem 'guard-bundler'
|
12
|
+
gem 'guard-rspec'
|
data/Guardfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
guard 'bundler' do
|
2
|
+
watch('Gemfile')
|
3
|
+
watch(/^.+\.gemspec/)
|
4
|
+
end
|
5
|
+
|
6
|
+
guard 'rspec', :version => 2, :cli => '--color --format nested', :all_on_start => true, :all_after_pass => true do
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
watch(%r{^spec/.+_spec\.rb$})
|
9
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
10
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Matt Wilson
|
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,95 @@
|
|
1
|
+
# Duration
|
2
|
+
|
3
|
+
Provides simple (somewhat naive) Duration parsing from strings. Allows you to compare and modify durations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rduration', :require => 'duration'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rduration
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
`duration_spec.rb` has more details about the types of strings this can handle, but here's brief overview:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
a = Duration.new("01:46:00")
|
25
|
+
b = Duration.new("25 minutes 17 seconds")
|
26
|
+
a > b # => true
|
27
|
+
a - b # => #<Duration:2164349940 @raw="4843">
|
28
|
+
[b, a].sort # => [a, b]
|
29
|
+
|
30
|
+
b.to_clock_format # => "25:17"
|
31
|
+
```
|
32
|
+
|
33
|
+
If you require 'duration/string_ext' then strings gain a new method: `#to_duration`
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
"35m 5s".to_duration # => NoMethodError: undefined method `to_duration' for "35m 5s":String
|
37
|
+
|
38
|
+
require 'duration/string_ext'
|
39
|
+
"35m 5s".to_duration # => #<Duration:2151903540 @raw="35m 5s">
|
40
|
+
|
41
|
+
# once you've done this, the arithmetic and comparison stuff works too
|
42
|
+
"35m 5s".to_duration > "10m" # => true
|
43
|
+
"35m 5s".to_duration > "50m" # => false
|
44
|
+
"35m 5s".to_duration + "10m" # => #<Duration:2156162420 @raw="2705">
|
45
|
+
```
|
46
|
+
|
47
|
+
### Formats
|
48
|
+
|
49
|
+
Here's a list of formats that will parse:
|
50
|
+
|
51
|
+
```
|
52
|
+
Duration
|
53
|
+
#parse
|
54
|
+
parses "0" as 0 seconds
|
55
|
+
parses "00:00" as 0 seconds
|
56
|
+
parses "0 seconds" as 0 seconds
|
57
|
+
parses nil as 0 seconds
|
58
|
+
parses "45s" as 45 seconds
|
59
|
+
parses "45 seconds" as 45 seconds
|
60
|
+
parses "00:00:45" as 45 seconds
|
61
|
+
parses "45" as 45 seconds
|
62
|
+
parses "137s" as 137 seconds
|
63
|
+
parses "2m17s" as 137 seconds
|
64
|
+
parses "2 minutes 17 seconds" as 137 seconds
|
65
|
+
parses "02:17" as 137 seconds
|
66
|
+
parses "2:17" as 137 seconds
|
67
|
+
parses "1h32m07s" as 5527 seconds
|
68
|
+
parses "1:32:07" as 5527 seconds
|
69
|
+
parses "92 minutes and 7 seconds" as 5527 seconds
|
70
|
+
parses "3d10h15m" as 296100 seconds
|
71
|
+
parses "3:10:15:00" as 296100 seconds
|
72
|
+
parses "82 hours 15 minutes" as 296100 seconds
|
73
|
+
```
|
74
|
+
|
75
|
+
### Interesting Methods
|
76
|
+
|
77
|
+
* `#to_clock_format` leverages `#to_s`'s newfound proc handling powers to format the output. Speaking of...
|
78
|
+
* `#to_s` takes a proc, and yields the duration in seconds to it. This is useful for output.
|
79
|
+
|
80
|
+
## CHANGELOG
|
81
|
+
|
82
|
+
* **v0.0.1 Hello World**
|
83
|
+
* Handles all of my use cases. Could be better at everything, though :).
|
84
|
+
|
85
|
+
## Contributing
|
86
|
+
|
87
|
+
1. Fork it
|
88
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
89
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
90
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
91
|
+
5. Create new Pull Request
|
92
|
+
|
93
|
+
## Copyright
|
94
|
+
|
95
|
+
Copyright (c) 2012 Matt Wilson. See LICENSE for details, but it's MIT.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Duration
|
2
|
+
module Arithmatic
|
3
|
+
def + other_duration
|
4
|
+
raise StandardError.new("Cannot add #{other_duration.class} to #{self}") unless other_duration.respond_to?(:to_i)
|
5
|
+
other_duration = other_duration.to_duration if other_duration.respond_to?(:to_duration)
|
6
|
+
Duration.new(self.to_i + other_duration.to_i)
|
7
|
+
end
|
8
|
+
|
9
|
+
def - other_duration
|
10
|
+
raise StandardError.new("Cannot subtract #{other_duration.class} from #{self}") unless other_duration.respond_to?(:to_i)
|
11
|
+
other_duration = other_duration.to_duration if other_duration.respond_to?(:to_duration)
|
12
|
+
Duration.new(self.to_i - other_duration.to_i)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/duration.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require "duration/version"
|
2
|
+
require "duration/arithmatic"
|
3
|
+
|
4
|
+
class Duration
|
5
|
+
attr_accessor :raw
|
6
|
+
|
7
|
+
include Comparable
|
8
|
+
include Arithmatic
|
9
|
+
|
10
|
+
def initialize input
|
11
|
+
self.raw = input.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse
|
15
|
+
@parsed ||= count normalize_input
|
16
|
+
end
|
17
|
+
alias_method :to_i, :parse
|
18
|
+
|
19
|
+
def normalize_input input = raw.dup
|
20
|
+
input = condense_duration_tokens input # => '92 m and 7 s'
|
21
|
+
input = strip_useless_words input # => '92 m 7 s'
|
22
|
+
input = intelligently_space input # => '92m 7s'
|
23
|
+
convert_to_normal_form input # '92:07' => '92m 7s'
|
24
|
+
end
|
25
|
+
|
26
|
+
def condense_duration_tokens input = raw.dup
|
27
|
+
input.gsub(/(#{DURATIONS.keys.join("|")})/, DURATIONS)
|
28
|
+
end
|
29
|
+
|
30
|
+
def strip_useless_words input = raw.dup
|
31
|
+
input.gsub(/[[:alpha:]]{2,}/, "").gsub(/[^\ddhms:]/, " ").squeeze(" ")
|
32
|
+
end
|
33
|
+
|
34
|
+
def intelligently_space input = raw.dup
|
35
|
+
input.gsub(/\s/, "").gsub(/([[:alpha:]])(?=[[:digit:]])/, '\1 ')
|
36
|
+
end
|
37
|
+
|
38
|
+
def convert_to_normal_form input = raw.dup
|
39
|
+
return input unless input =~ /:/ || input !~ /[[:alpha:]]/
|
40
|
+
split = input.split(":").reverse
|
41
|
+
split.zip(UNITS).reverse.map { |unit| unit.join("") }.join(" ")
|
42
|
+
end
|
43
|
+
|
44
|
+
def hashify string
|
45
|
+
string.split(" ").inject({}) do |accum, token|
|
46
|
+
_, amount, type = token.split(/([[:digit:]]+)(?=[[:alpha:]])/)
|
47
|
+
accum[type] = amount.to_i
|
48
|
+
accum
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def count input = normalize_input
|
53
|
+
hashify(input).inject(0) do |accum, (unit, how_many)|
|
54
|
+
accum += how_many * STANDARD_CONVERSION[unit]
|
55
|
+
accum
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_clock_format
|
60
|
+
to_s proc { |s|
|
61
|
+
a = STANDARD_CONVERSION.values.dup
|
62
|
+
[(s / a[3]), (s % a[3] / a[2]), (s % a[2] / a[1]), (s % a[1])].
|
63
|
+
each_with_index.
|
64
|
+
reject { |value, index| index < 2 && value == 0 }.
|
65
|
+
map { |value| "%02d" % value }.
|
66
|
+
join(":")
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s formatter = nil
|
71
|
+
formatter ? formatter.call(parse) : "#<Duration:#{self.object_id} @raw=#{raw.inspect} @clock=#{to_clock_format.inspect}>"
|
72
|
+
end
|
73
|
+
|
74
|
+
UNITS = ['s', 'm', 'h', 'd']
|
75
|
+
|
76
|
+
DURATIONS = {
|
77
|
+
'seconds' => 's',
|
78
|
+
'minutes' => 'm',
|
79
|
+
'hours' => 'h',
|
80
|
+
'days' => 'd',
|
81
|
+
'sec' => 's',
|
82
|
+
'hrs' => 'h',
|
83
|
+
'mins' => 'm'
|
84
|
+
}
|
85
|
+
DURATIONS.default_proc = proc { |hash, key| hash[key] = "" }
|
86
|
+
|
87
|
+
STANDARD_CONVERSION = {
|
88
|
+
's' => 1,
|
89
|
+
'm' => 60,
|
90
|
+
'h' => 3600,
|
91
|
+
'd' => 86_400
|
92
|
+
}
|
93
|
+
|
94
|
+
# Comparable Protocol:
|
95
|
+
def <=> other_thing
|
96
|
+
other_thing = other_thing.to_duration if other_thing.respond_to?(:to_duration)
|
97
|
+
self.to_i <=> other_thing.to_i
|
98
|
+
end
|
99
|
+
end
|
data/rduration.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/duration/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.authors = ["Matt Wilson"]
|
6
|
+
s.email = ["mhw@hypomodern.com"]
|
7
|
+
s.description = %q{Simple utility for parsing durations from strings and comparing them. Basic math is also supported.}
|
8
|
+
s.summary = %q{Parse durations from strings and manipulate them.}
|
9
|
+
s.homepage = "https://github.com/hypomodern/rduration"
|
10
|
+
|
11
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.name = "rduration"
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.version = Duration::VERSION
|
17
|
+
|
18
|
+
s.add_development_dependency 'rake'
|
19
|
+
s.add_development_dependency 'rspec'
|
20
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Duration do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "stores the raw input string in an attribute called #raw" do
|
6
|
+
d = Duration.new("00:01")
|
7
|
+
d.raw.should == "00:01"
|
8
|
+
end
|
9
|
+
it "coerces the input to a string" do
|
10
|
+
d = Duration.new(nil)
|
11
|
+
d.raw.should == ""
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#parse" do
|
16
|
+
expected_second_values_and_their_strings = {
|
17
|
+
0 => [ '0', '00:00', '0 seconds', nil ],
|
18
|
+
45 => [ '45s', '45 seconds', '00:00:45', '45' ],
|
19
|
+
137 => [ '137s', '2m17s', '2 minutes 17 seconds', '02:17', '2:17' ],
|
20
|
+
5_527 => [ '1h32m07s', '1:32:07', '92 minutes and 7 seconds' ],
|
21
|
+
296_100 => [ '3d10h15m', '3:10:15:00', '82 hours 15 minutes' ]
|
22
|
+
}
|
23
|
+
expected_second_values_and_their_strings.each do |(expected, inputs)|
|
24
|
+
inputs.each do |possible_input|
|
25
|
+
it "parses #{possible_input.inspect} as #{expected} seconds" do
|
26
|
+
Duration.new(possible_input).parse.should == expected
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#to_i" do
|
33
|
+
it "is an alias for #parse" do
|
34
|
+
Duration.new('45s').to_i.should == 45
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#normalize_input" do
|
39
|
+
normal_form_and_variants = {
|
40
|
+
'45s' => [ '45s', '45 seconds', '45' ],
|
41
|
+
'00h 00m 45s' => ['00:00:45'],
|
42
|
+
'2m 17s' => [ '2m17s', '2 minutes 17 seconds', '2:17','2m 17s' ],
|
43
|
+
'137s' => ['137s'],
|
44
|
+
'1h 32m 07s' => [ '1h32m07s', '1:32:07', '1h 32m 07s' ],
|
45
|
+
'3d 10h 15m 00s' => [ '3d10h15m00s', '3:10:15:00', '3d 10h 15m 00s' ],
|
46
|
+
'82h 15m' => ['82 hours, 15 minutes'],
|
47
|
+
'92m 7s' => ['92 minutes and 7 seconds']
|
48
|
+
}
|
49
|
+
normal_form_and_variants.each do |(expected, inputs)|
|
50
|
+
inputs.each do |input|
|
51
|
+
it "normalizes #{input.inspect} to #{expected.inspect}" do
|
52
|
+
Duration.new(input).normalize_input.should == expected
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
it "doesn't modify the #raw attibute" do
|
57
|
+
input = '92 minutes and 7 seconds'
|
58
|
+
Duration.new(input).tap { |s| s.normalize_input }.raw.should == input
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#condense_duration_tokens" do
|
63
|
+
forms_to_condense = {
|
64
|
+
'2 minutes 17 seconds' => '2 m 17 s',
|
65
|
+
'3 days 10 hours 15 minutes' => '3 d 10 h 15 m',
|
66
|
+
'2:17' => '2:17'
|
67
|
+
}
|
68
|
+
forms_to_condense.each do |(input, expectation)|
|
69
|
+
it "converts #{input.inspect} into #{expectation.inspect}" do
|
70
|
+
Duration.new(input).condense_duration_tokens.should == expectation
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#strip_useless_words" do
|
76
|
+
forms_with_useless_words = {
|
77
|
+
'92 m and 7 s' => '92 m 7 s',
|
78
|
+
'3 d, 8 h, and 11 m' => '3 d 8 h 11 m',
|
79
|
+
'3m + 18s' => '3m 18s',
|
80
|
+
'2:17' => '2:17'
|
81
|
+
}
|
82
|
+
forms_with_useless_words.each do |(input, expectation)|
|
83
|
+
it "converts #{input.inspect} to #{expectation.inspect}" do
|
84
|
+
Duration.new(input).strip_useless_words.should == expectation
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#intelligently_space" do
|
90
|
+
spaced_out_forms = {
|
91
|
+
'1h32m07s' => '1h 32m 07s',
|
92
|
+
'92 m 7 s' => '92m 7s',
|
93
|
+
'3 d 8 h 11 m' => '3d 8h 11m',
|
94
|
+
'3m 18s' => '3m 18s',
|
95
|
+
'2:17' => '2:17'
|
96
|
+
}
|
97
|
+
spaced_out_forms.each do |(input, expectation)|
|
98
|
+
it "converts #{input.inspect} to #{expectation.inspect}" do
|
99
|
+
Duration.new(input).intelligently_space.should == expectation
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#convert_to_normal_form" do
|
105
|
+
clock_forms = {
|
106
|
+
'1:32:07' => '1h 32m 07s',
|
107
|
+
'92:07' => '92m 07s',
|
108
|
+
'03:08:11:00' => '03d 08h 11m 00s',
|
109
|
+
'03:00' => '03m 00s',
|
110
|
+
'2m 17s' => '2m 17s',
|
111
|
+
'45' => '45s'
|
112
|
+
}
|
113
|
+
clock_forms.each do |(input, expectation)|
|
114
|
+
it "converts #{input.inspect} to #{expectation.inspect}" do
|
115
|
+
Duration.new(input).convert_to_normal_form.should == expectation
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#hashify" do
|
121
|
+
it "maps a string to an easily-countable hash form" do
|
122
|
+
Duration.new("42m 3s").hashify("42m 3s").should == {
|
123
|
+
"m" => 42,
|
124
|
+
"s" => 3
|
125
|
+
}
|
126
|
+
end
|
127
|
+
normalized_inputs = {
|
128
|
+
'1h 32m 07s' => { 'h' => 1, 'm' => 32, 's' => 7 },
|
129
|
+
'03d 08h 11m 00s' => { 'd' => 3, 'h' => 8, 'm' => 11, 's' => 0 },
|
130
|
+
}
|
131
|
+
normalized_inputs.each do |(input, expectation)|
|
132
|
+
it "converts #{input.inspect} to #{expectation.inspect}" do
|
133
|
+
Duration.new(input).hashify(input).should == expectation
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#to_clock_format" do
|
139
|
+
clocks = {
|
140
|
+
0 => '00:00',
|
141
|
+
45 => '00:45',
|
142
|
+
137 => '02:17',
|
143
|
+
5_527 => '01:32:07',
|
144
|
+
296_100 => '03:10:15:00'
|
145
|
+
}
|
146
|
+
clocks.each do |seconds, formatted|
|
147
|
+
it "outputs #{formatted.inspect} given #{seconds} seconds" do
|
148
|
+
Duration.new(seconds).to_clock_format.should == formatted
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "#to_s" do
|
154
|
+
context "but with a formatter proc/lambda" do
|
155
|
+
it "calls the formatter, yielding the current number of seconds" do
|
156
|
+
formatted = Duration.new(500).to_s proc { |s| "Mein formatt sagt #{s}" }
|
157
|
+
formatted.should == "Mein formatt sagt 500"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
it "just returns something like #to_s normally does" do
|
161
|
+
d = Duration.new(500)
|
162
|
+
d.to_s.should == "#<Duration:#{d.object_id} @raw=\"500\" @clock=\"08:20\">"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "Comparable compatibility" do
|
167
|
+
describe "#<=>" do
|
168
|
+
it "compares Durations based on their #to_i values" do
|
169
|
+
( Duration.new("01:04:55") > Duration.new("55m 3s") ).should be_true
|
170
|
+
( Duration.new("55m 3s") > Duration.new("30 minutes and 14 seconds") ).should be_true
|
171
|
+
( Duration.new("04:22") > Duration.new("75") ).should be_true
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "basic maths" do
|
177
|
+
let(:a) { Duration.new("55 seconds") }
|
178
|
+
let(:b) { Duration.new("1m 10s") }
|
179
|
+
describe "#+" do
|
180
|
+
it "returns a new Duration..." do
|
181
|
+
added = a + b
|
182
|
+
added.should be_a_kind_of(Duration)
|
183
|
+
[a.object_id, b.object_id].should_not include(added.object_id)
|
184
|
+
end
|
185
|
+
it "sums the two Durations by seconds" do
|
186
|
+
added = a+b
|
187
|
+
added.to_i.should == 125
|
188
|
+
added.to_clock_format.should == "02:05"
|
189
|
+
end
|
190
|
+
end
|
191
|
+
describe "#-" do
|
192
|
+
it "returns a new Duration..." do
|
193
|
+
difference = b - a
|
194
|
+
difference.should be_a_kind_of(Duration)
|
195
|
+
[a.object_id, b.object_id].should_not include(difference.object_id)
|
196
|
+
end
|
197
|
+
it "subtracts the two Durations by seconds" do
|
198
|
+
difference = b - a
|
199
|
+
difference.to_i.should == 15
|
200
|
+
difference.to_clock_format.should == "00:15"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'duration' # and any other gems you need
|
5
|
+
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rduration
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Wilson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &2156379680 !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: *2156379680
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &2156379180 !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: *2156379180
|
36
|
+
description: Simple utility for parsing durations from strings and comparing them.
|
37
|
+
Basic math is also supported.
|
38
|
+
email:
|
39
|
+
- mhw@hypomodern.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- .rspec
|
46
|
+
- .rvmrc
|
47
|
+
- Gemfile
|
48
|
+
- Guardfile
|
49
|
+
- LICENSE
|
50
|
+
- README.md
|
51
|
+
- Rakefile
|
52
|
+
- lib/duration.rb
|
53
|
+
- lib/duration/arithmatic.rb
|
54
|
+
- lib/duration/string_ext.rb
|
55
|
+
- lib/duration/version.rb
|
56
|
+
- rduration.gemspec
|
57
|
+
- spec/duration/string_ext_spec.rb
|
58
|
+
- spec/duration_spec.rb
|
59
|
+
- spec/spec_helper.rb
|
60
|
+
homepage: https://github.com/hypomodern/rduration
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.8.17
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Parse durations from strings and manipulate them.
|
84
|
+
test_files:
|
85
|
+
- spec/duration/string_ext_spec.rb
|
86
|
+
- spec/duration_spec.rb
|
87
|
+
- spec/spec_helper.rb
|