chronic_duration 0.9.6 → 0.10.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.
- data/.gitignore +17 -0
- data/Gemfile +1 -9
- data/{README.rdoc → README.md} +16 -15
- data/Rakefile +2 -41
- data/chronic_duration.gemspec +20 -56
- data/lib/chronic_duration.rb +78 -57
- data/lib/chronic_duration/version.rb +3 -0
- data/spec/chronic_duration_spec.rb +80 -47
- data/spec/lib/chronic_duration_spec.rb +212 -0
- data/spec/spec_helper.rb +8 -0
- metadata +69 -79
- data/Gemfile.lock +0 -30
- data/VERSION +0 -1
data/.gitignore
ADDED
data/Gemfile
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,15 +1,10 @@
|
|
1
|
-
|
1
|
+
# Chronic Duration
|
2
2
|
|
3
|
-
A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.)
|
3
|
+
A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.)
|
4
4
|
|
5
|
-
The reverse can also be accomplished with the output method.
|
5
|
+
The reverse can also be accomplished with the output method. So pass in seconds and you can get strings like 4 mins 31.51 secs (default format), 4h 3m 30s, or 4:01:29.
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
$ sudo gem sources -a http://gemcutter.org
|
10
|
-
$ sudo gem install chronic_duration
|
11
|
-
|
12
|
-
== Usage
|
7
|
+
## Usage
|
13
8
|
|
14
9
|
>> require 'chronic_duration'
|
15
10
|
=> true
|
@@ -23,13 +18,19 @@ The reverse can also be accomplished with the output method. So pass in seconds
|
|
23
18
|
=> 4 minutes 30 seconds
|
24
19
|
>> ChronicDuration.output(270, :format => :chrono)
|
25
20
|
=> 4:30
|
26
|
-
|
21
|
+
>> ChronicDuration.output(1299600, :weeks => true)
|
22
|
+
=> 2 wks 1 day 1 hr
|
23
|
+
>> ChronicDuration.output(1299600, :weeks => true, :units => 2)
|
24
|
+
=> 2 wks 1 day
|
25
|
+
>> ChronicDuration.output(1296000)
|
26
|
+
=> 15 days
|
27
|
+
|
27
28
|
Nil is returned if the string can't be parsed
|
28
29
|
|
29
30
|
Examples of parse-able strings:
|
30
31
|
|
31
32
|
* '12.4 secs'
|
32
|
-
* '1:20'
|
33
|
+
* '1:20'
|
33
34
|
* '1:20.51'
|
34
35
|
* '4:01:01'
|
35
36
|
* '3 mins 4 sec'
|
@@ -47,12 +48,12 @@ ChronicDuration.raise_exceptions can be set to true to raise exceptions when the
|
|
47
48
|
>> ChronicDuration.parse('4 elephants and 3 Astroids')
|
48
49
|
ChronicDuration::DurationParseError: An invalid word "elephants" was used in the string to be parsed.
|
49
50
|
|
50
|
-
|
51
|
-
|
51
|
+
|
52
|
+
## Contributors
|
52
53
|
|
53
54
|
brianjlandau, jduff, olauzon, roboman, ianlevesque
|
54
|
-
|
55
|
-
|
55
|
+
|
56
|
+
## TODO
|
56
57
|
|
57
58
|
* Benchmark, optimize
|
58
59
|
* Context specific matching (E.g., for '4m30s', assume 'm' is minutes not months)
|
data/Rakefile
CHANGED
@@ -1,45 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require 'bundler'
|
3
|
-
begin
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require 'rake'
|
11
|
-
|
12
|
-
require 'jeweler'
|
13
|
-
Jeweler::Tasks.new do |gem|
|
14
|
-
gem.name = "chronic_duration"
|
15
|
-
gem.summary = %Q{A Ruby natural language parser for elapsed time}
|
16
|
-
gem.license = "MIT"
|
17
|
-
gem.description = %Q{A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.) The reverse can also be performed via the output method.}
|
18
|
-
gem.email = "hpoydar@gmail.com"
|
19
|
-
gem.homepage = "http://github.com/hpoydar/chronic_duration"
|
20
|
-
gem.authors = ["hpoydar"]
|
21
|
-
end
|
22
|
-
Jeweler::RubygemsDotOrgTasks.new
|
23
|
-
|
24
|
-
require 'rspec/core'
|
1
|
+
require "bundler/gem_tasks"
|
25
2
|
require 'rspec/core/rake_task'
|
26
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
28
|
-
end
|
29
|
-
|
30
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
31
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
-
spec.rcov = true
|
33
|
-
end
|
34
3
|
|
4
|
+
RSpec::Core::RakeTask.new('spec')
|
35
5
|
task :default => :spec
|
36
6
|
|
37
|
-
require 'rake/rdoctask'
|
38
|
-
Rake::RDocTask.new do |rdoc|
|
39
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
-
|
41
|
-
rdoc.rdoc_dir = 'rdoc'
|
42
|
-
rdoc.title = "chronic_duration #{version}"
|
43
|
-
rdoc.rdoc_files.include('README*')
|
44
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
-
end
|
data/chronic_duration.gemspec
CHANGED
@@ -1,62 +1,26 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'chronic_duration/version'
|
5
5
|
|
6
|
-
Gem::Specification.new do |
|
7
|
-
s.name = %q{chronic_duration}
|
8
|
-
s.version = "0.9.6"
|
6
|
+
Gem::Specification.new do |gem|
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
]
|
18
|
-
s.files = [
|
19
|
-
"Gemfile",
|
20
|
-
"Gemfile.lock",
|
21
|
-
"MIT-LICENSE",
|
22
|
-
"README.rdoc",
|
23
|
-
"Rakefile",
|
24
|
-
"VERSION",
|
25
|
-
"chronic_duration.gemspec",
|
26
|
-
"lib/chronic_duration.rb",
|
27
|
-
"spec/chronic_duration_spec.rb"
|
28
|
-
]
|
29
|
-
s.homepage = %q{http://github.com/hpoydar/chronic_duration}
|
30
|
-
s.licenses = ["MIT"]
|
31
|
-
s.require_paths = ["lib"]
|
32
|
-
s.rubygems_version = %q{1.5.2}
|
33
|
-
s.summary = %q{A Ruby natural language parser for elapsed time}
|
34
|
-
s.test_files = [
|
35
|
-
"spec/chronic_duration_spec.rb"
|
36
|
-
]
|
8
|
+
gem.name = "chronic_duration"
|
9
|
+
gem.version = ChronicDuration::VERSION
|
10
|
+
gem.authors = ["hpoydar"]
|
11
|
+
gem.email = ["henry@poydar.com"]
|
12
|
+
gem.description = %q{A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.) The reverse can also be performed via the output method.}
|
13
|
+
gem.summary = %q{A simple Ruby natural language parser for elapsed time}
|
14
|
+
gem.homepage = "https://github.com/hpoydar/chronic_duration"
|
37
15
|
|
38
|
-
|
39
|
-
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
40
20
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
46
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
47
|
-
else
|
48
|
-
s.add_dependency(%q<numerizer>, ["~> 0.1.1"])
|
49
|
-
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
50
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
51
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
52
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
53
|
-
end
|
54
|
-
else
|
55
|
-
s.add_dependency(%q<numerizer>, ["~> 0.1.1"])
|
56
|
-
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
57
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
58
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
59
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
60
|
-
end
|
61
|
-
end
|
21
|
+
gem.add_runtime_dependency "numerizer", "~> 0.1.1"
|
22
|
+
|
23
|
+
gem.add_development_dependency "rake", "~> 10.0.3"
|
24
|
+
gem.add_development_dependency "rspec", "~> 2.12.0"
|
62
25
|
|
26
|
+
end
|
data/lib/chronic_duration.rb
CHANGED
@@ -1,40 +1,42 @@
|
|
1
1
|
require 'numerizer' unless defined?(Numerizer)
|
2
|
+
|
2
3
|
module ChronicDuration
|
4
|
+
|
3
5
|
extend self
|
4
|
-
|
6
|
+
|
5
7
|
class DurationParseError < StandardError
|
6
8
|
end
|
7
|
-
|
9
|
+
|
8
10
|
@@raise_exceptions = false
|
9
|
-
|
11
|
+
|
10
12
|
def self.raise_exceptions
|
11
13
|
!!@@raise_exceptions
|
12
14
|
end
|
13
|
-
|
15
|
+
|
14
16
|
def self.raise_exceptions=(value)
|
15
17
|
@@raise_exceptions = !!value
|
16
18
|
end
|
17
|
-
|
19
|
+
|
18
20
|
# Given a string representation of elapsed time,
|
19
21
|
# return an integer (or float, if fractions of a
|
20
22
|
# second are input)
|
21
23
|
def parse(string, opts = {})
|
22
24
|
result = calculate_from_words(cleanup(string), opts)
|
23
25
|
result == 0 ? nil : result
|
24
|
-
end
|
25
|
-
|
26
|
+
end
|
27
|
+
|
26
28
|
# Given an integer and an optional format,
|
27
29
|
# returns a formatted string representing elapsed time
|
28
30
|
def output(seconds, opts = {})
|
29
|
-
|
31
|
+
|
30
32
|
opts[:format] ||= :default
|
31
|
-
|
32
|
-
years = months = days = hours = minutes = 0
|
33
|
-
|
33
|
+
|
34
|
+
years = months = weeks = days = hours = minutes = 0
|
35
|
+
|
34
36
|
decimal_places = seconds.to_s.split('.').last.length if seconds.is_a?(Float)
|
35
37
|
|
36
38
|
if seconds >= 60
|
37
|
-
minutes = (seconds / 60).to_i
|
39
|
+
minutes = (seconds / 60).to_i
|
38
40
|
seconds = seconds % 60
|
39
41
|
if minutes >= 60
|
40
42
|
hours = (minutes / 60).to_i
|
@@ -42,40 +44,52 @@ module ChronicDuration
|
|
42
44
|
if hours >= 24
|
43
45
|
days = (hours / 24).to_i
|
44
46
|
hours = (hours % 24).to_i
|
45
|
-
if
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
if opts[:weeks]
|
48
|
+
if days >= 7
|
49
|
+
weeks = (days / 7).to_i
|
50
|
+
days = (days % 7).to_i
|
51
|
+
if weeks >= 4
|
52
|
+
months = (weeks / 4).to_i
|
53
|
+
weeks = (weeks % 4).to_i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
if days >= 30
|
58
|
+
months = (days / 30).to_i
|
59
|
+
days = (days % 30).to_i
|
51
60
|
end
|
52
61
|
end
|
62
|
+
if months >= 12
|
63
|
+
years = (months / 12).to_i
|
64
|
+
months = (months % 12).to_i
|
65
|
+
days = days - (5 * years)
|
66
|
+
end
|
53
67
|
end
|
54
68
|
end
|
55
69
|
end
|
56
|
-
|
70
|
+
|
57
71
|
joiner = ' '
|
58
72
|
process = nil
|
59
|
-
|
73
|
+
|
60
74
|
case opts[:format]
|
61
75
|
when :micro
|
62
|
-
dividers = {
|
63
|
-
:years => 'y', :months => '
|
76
|
+
dividers = {
|
77
|
+
:years => 'y', :months => 'mo', :weeks => 'w', :days => 'd', :hours => 'h', :minutes => 'm', :seconds => 's' }
|
64
78
|
joiner = ''
|
65
79
|
when :short
|
66
|
-
dividers = {
|
67
|
-
:years => 'y', :months => 'm', :days => 'd', :hours => 'h', :minutes => 'm', :seconds => 's' }
|
68
|
-
when :default
|
69
80
|
dividers = {
|
70
|
-
:years => '
|
81
|
+
:years => 'y', :months => 'mo', :weeks => 'w', :days => 'd', :hours => 'h', :minutes => 'm', :seconds => 's' }
|
82
|
+
when :default
|
83
|
+
dividers = {
|
84
|
+
:years => ' yr', :months => ' mo', :weeks => ' wk', :days => ' day', :hours => ' hr', :minutes => ' min', :seconds => ' sec',
|
71
85
|
:pluralize => true }
|
72
|
-
when :long
|
86
|
+
when :long
|
73
87
|
dividers = {
|
74
|
-
:years => ' year', :months => ' month', :days => ' day', :hours => ' hour', :minutes => ' minute', :seconds => ' second',
|
88
|
+
:years => ' year', :months => ' month', :weeks => ' week', :days => ' day', :hours => ' hour', :minutes => ' minute', :seconds => ' second',
|
75
89
|
:pluralize => true }
|
76
90
|
when :chrono
|
77
91
|
dividers = {
|
78
|
-
:years => ':', :months => ':', :days => ':', :hours => ':', :minutes => ':', :seconds => ':', :keep_zero => true }
|
92
|
+
:years => ':', :months => ':', :weeks => ':', :days => ':', :hours => ':', :minutes => ':', :seconds => ':', :keep_zero => true }
|
79
93
|
process = lambda do |str|
|
80
94
|
# Pad zeros
|
81
95
|
# Get rid of lead off times if they are zero
|
@@ -85,34 +99,36 @@ module ChronicDuration
|
|
85
99
|
end
|
86
100
|
joiner = ''
|
87
101
|
end
|
88
|
-
|
89
|
-
result = []
|
90
|
-
|
102
|
+
|
103
|
+
result = [:years, :months, :weeks, :days, :hours, :minutes, :seconds].map do |t|
|
104
|
+
next if t == :weeks && !opts[:weeks]
|
91
105
|
num = eval(t.to_s)
|
92
|
-
num = ("%.#{decimal_places}f" % num) if num.is_a?(Float) && t == :seconds
|
93
|
-
|
94
|
-
end
|
106
|
+
num = ("%.#{decimal_places}f" % num) if num.is_a?(Float) && t == :seconds
|
107
|
+
humanize_time_unit( num, dividers[t], dividers[:pluralize], dividers[:keep_zero] )
|
108
|
+
end.compact!
|
109
|
+
|
110
|
+
result = result[0...opts[:units]] if opts[:units]
|
111
|
+
|
112
|
+
result = result.join(joiner)
|
95
113
|
|
96
|
-
result = result.join(joiner).squeeze(' ').strip
|
97
|
-
|
98
114
|
if process
|
99
115
|
result = process.call(result)
|
100
116
|
end
|
101
|
-
|
117
|
+
|
102
118
|
result.length == 0 ? nil : result
|
103
119
|
|
104
120
|
end
|
105
|
-
|
121
|
+
|
106
122
|
private
|
107
|
-
|
123
|
+
|
108
124
|
def humanize_time_unit(number, unit, pluralize, keep_zero)
|
109
|
-
return
|
125
|
+
return nil if number == 0 && !keep_zero
|
110
126
|
res = "#{number}#{unit}"
|
111
127
|
# A poor man's pluralizer
|
112
128
|
res << 's' if !(number == 1) && pluralize
|
113
129
|
res
|
114
130
|
end
|
115
|
-
|
131
|
+
|
116
132
|
def calculate_from_words(string, opts)
|
117
133
|
val = 0
|
118
134
|
words = string.split(' ')
|
@@ -123,18 +139,18 @@ private
|
|
123
139
|
end
|
124
140
|
val
|
125
141
|
end
|
126
|
-
|
142
|
+
|
127
143
|
def cleanup(string)
|
128
144
|
res = string.downcase
|
129
145
|
res = filter_by_type(Numerizer.numerize(res))
|
130
146
|
res = res.gsub(float_matcher) {|n| " #{n} "}.squeeze(' ').strip
|
131
147
|
res = filter_through_white_list(res)
|
132
148
|
end
|
133
|
-
|
149
|
+
|
134
150
|
def convert_to_number(string)
|
135
151
|
string.to_f % 1 > 0 ? string.to_f : string.to_i
|
136
152
|
end
|
137
|
-
|
153
|
+
|
138
154
|
def duration_units_list
|
139
155
|
%w(seconds minutes hours days weeks months years)
|
140
156
|
end
|
@@ -150,18 +166,19 @@ private
|
|
150
166
|
when 'seconds'; 1
|
151
167
|
end
|
152
168
|
end
|
153
|
-
|
169
|
+
|
154
170
|
def error_message
|
155
171
|
'Sorry, that duration could not be parsed'
|
156
172
|
end
|
157
|
-
|
173
|
+
|
158
174
|
# Parse 3:41:59 and return 3 hours 41 minutes 59 seconds
|
159
175
|
def filter_by_type(string)
|
176
|
+
chrono_units_list = duration_units_list.reject {|v| v == "weeks"}
|
160
177
|
if string.gsub(' ', '') =~ /#{float_matcher}(:#{float_matcher})+/
|
161
178
|
res = []
|
162
179
|
string.gsub(' ', '').split(':').reverse.each_with_index do |v,k|
|
163
|
-
return unless
|
164
|
-
res << "#{v} #{
|
180
|
+
return unless chrono_units_list[k]
|
181
|
+
res << "#{v} #{chrono_units_list[k]}"
|
165
182
|
end
|
166
183
|
res = res.reverse.join(' ')
|
167
184
|
else
|
@@ -169,11 +186,11 @@ private
|
|
169
186
|
end
|
170
187
|
res
|
171
188
|
end
|
172
|
-
|
189
|
+
|
173
190
|
def float_matcher
|
174
191
|
/[0-9]*\.?[0-9]+/
|
175
192
|
end
|
176
|
-
|
193
|
+
|
177
194
|
# Get rid of unknown words and map found
|
178
195
|
# words to defined time units
|
179
196
|
def filter_through_white_list(string)
|
@@ -190,11 +207,13 @@ private
|
|
190
207
|
raise DurationParseError, "An invalid word #{word.inspect} was used in the string to be parsed."
|
191
208
|
end
|
192
209
|
end
|
210
|
+
# add '1' at front if string starts with something recognizable but not with a number, like 'day' or 'minute 30sec'
|
211
|
+
res.unshift(1) if res.length > 0 && mappings[res[0]]
|
193
212
|
res.join(' ')
|
194
213
|
end
|
195
|
-
|
214
|
+
|
196
215
|
def mappings
|
197
|
-
{
|
216
|
+
{
|
198
217
|
'seconds' => 'seconds',
|
199
218
|
'second' => 'seconds',
|
200
219
|
'secs' => 'seconds',
|
@@ -218,21 +237,23 @@ private
|
|
218
237
|
'week' => 'weeks',
|
219
238
|
'w' => 'weeks',
|
220
239
|
'months' => 'months',
|
240
|
+
'mo' => 'months',
|
221
241
|
'mos' => 'months',
|
222
242
|
'month' => 'months',
|
223
243
|
'years' => 'years',
|
224
244
|
'year' => 'years',
|
225
245
|
'yrs' => 'years',
|
246
|
+
'yr' => 'years',
|
226
247
|
'y' => 'years'
|
227
248
|
}
|
228
249
|
end
|
229
|
-
|
250
|
+
|
230
251
|
def join_words
|
231
252
|
['and', 'with', 'plus']
|
232
253
|
end
|
233
|
-
|
254
|
+
|
234
255
|
def white_list
|
235
|
-
self.mappings.
|
256
|
+
self.mappings.keys
|
236
257
|
end
|
237
|
-
|
258
|
+
|
238
259
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'chronic_duration'
|
2
2
|
|
3
3
|
describe ChronicDuration, '.parse' do
|
4
|
-
|
5
|
-
@exemplars = {
|
4
|
+
|
5
|
+
@exemplars = {
|
6
6
|
'1:20' => 60 + 20,
|
7
7
|
'1:20.51' => 60 + 20.51,
|
8
8
|
'4:01:01' => 4 * 3600 + 60 + 1,
|
@@ -22,47 +22,49 @@ describe ChronicDuration, '.parse' do
|
|
22
22
|
'3 weeks, plus 2 days' => 3600 * 24 * 7 * 3 + 3600 * 24 * 2,
|
23
23
|
'3 weeks with 2 days' => 3600 * 24 * 7 * 3 + 3600 * 24 * 2,
|
24
24
|
'1 month' => 3600 * 24 * 30,
|
25
|
-
'2 months' => 3600 * 24 * 30 * 2
|
25
|
+
'2 months' => 3600 * 24 * 30 * 2,
|
26
|
+
'day' => 3600 * 24,
|
27
|
+
'minute 30s' => 90
|
26
28
|
}
|
27
|
-
|
29
|
+
|
28
30
|
it "should return nil if the string can't be parsed" do
|
29
31
|
ChronicDuration.parse('gobblygoo').should be_nil
|
30
32
|
end
|
31
|
-
|
33
|
+
|
32
34
|
it "should raise an exception if the string can't be parsed and @@raise_exceptions is set to true" do
|
33
35
|
ChronicDuration.raise_exceptions = true
|
34
36
|
lambda { ChronicDuration.parse('23 gobblygoos') }.should raise_exception(ChronicDuration::DurationParseError)
|
35
37
|
ChronicDuration.raise_exceptions = false
|
36
38
|
end
|
37
|
-
|
39
|
+
|
38
40
|
it "should return a float if seconds are in decimals" do
|
39
41
|
ChronicDuration.parse('12 mins 3.141 seconds').is_a?(Float).should be_true
|
40
42
|
end
|
41
|
-
|
43
|
+
|
42
44
|
it "should return an integer unless the seconds are in decimals" do
|
43
45
|
ChronicDuration.parse('12 mins 3 seconds').is_a?(Integer).should be_true
|
44
46
|
end
|
45
|
-
|
47
|
+
|
46
48
|
it "should be able to parse minutes by default" do
|
47
49
|
ChronicDuration.parse('5', :default_unit => "minutes").should == 300
|
48
50
|
end
|
49
|
-
|
51
|
+
|
50
52
|
@exemplars.each do |k, v|
|
51
53
|
it "should properly parse a duration like #{k}" do
|
52
54
|
ChronicDuration.parse(k).should == v
|
53
55
|
end
|
54
56
|
end
|
55
|
-
|
57
|
+
|
56
58
|
end
|
57
59
|
|
58
60
|
describe ChronicDuration, '.output' do
|
59
|
-
|
61
|
+
|
60
62
|
it "should return nil if the input can't be parsed" do
|
61
63
|
ChronicDuration.parse('gobblygoo').should be_nil
|
62
64
|
end
|
63
|
-
|
64
|
-
@exemplars = {
|
65
|
-
#(0) =>
|
65
|
+
|
66
|
+
@exemplars = {
|
67
|
+
#(0) =>
|
66
68
|
#{
|
67
69
|
#:micro => '0s',
|
68
70
|
#:short => '0s',
|
@@ -70,64 +72,80 @@ describe ChronicDuration, '.output' do
|
|
70
72
|
#:long => '0 seconds',
|
71
73
|
#:chrono => '0'
|
72
74
|
#},
|
73
|
-
(60 + 20) =>
|
74
|
-
{
|
75
|
+
(60 + 20) =>
|
76
|
+
{
|
75
77
|
:micro => '1m20s',
|
76
78
|
:short => '1m 20s',
|
77
79
|
:default => '1 min 20 secs',
|
78
80
|
:long => '1 minute 20 seconds',
|
79
81
|
:chrono => '1:20'
|
80
82
|
},
|
81
|
-
(60 + 20.51) =>
|
82
|
-
{
|
83
|
+
(60 + 20.51) =>
|
84
|
+
{
|
83
85
|
:micro => '1m20.51s',
|
84
86
|
:short => '1m 20.51s',
|
85
87
|
:default => '1 min 20.51 secs',
|
86
88
|
:long => '1 minute 20.51 seconds',
|
87
89
|
:chrono => '1:20.51'
|
88
90
|
},
|
89
|
-
(60 + 20.51928) =>
|
90
|
-
{
|
91
|
+
(60 + 20.51928) =>
|
92
|
+
{
|
91
93
|
:micro => '1m20.51928s',
|
92
94
|
:short => '1m 20.51928s',
|
93
95
|
:default => '1 min 20.51928 secs',
|
94
96
|
:long => '1 minute 20.51928 seconds',
|
95
97
|
:chrono => '1:20.51928'
|
96
98
|
},
|
97
|
-
(4 * 3600 + 60 + 1) =>
|
98
|
-
{
|
99
|
+
(4 * 3600 + 60 + 1) =>
|
100
|
+
{
|
99
101
|
:micro => '4h1m1s',
|
100
102
|
:short => '4h 1m 1s',
|
101
103
|
:default => '4 hrs 1 min 1 sec',
|
102
104
|
:long => '4 hours 1 minute 1 second',
|
103
105
|
:chrono => '4:01:01'
|
104
106
|
},
|
105
|
-
(2 * 3600 + 20 * 60) =>
|
106
|
-
{
|
107
|
+
(2 * 3600 + 20 * 60) =>
|
108
|
+
{
|
107
109
|
:micro => '2h20m',
|
108
110
|
:short => '2h 20m',
|
109
111
|
:default => '2 hrs 20 mins',
|
110
112
|
:long => '2 hours 20 minutes',
|
111
113
|
:chrono => '2:20'
|
112
114
|
},
|
113
|
-
(2 * 3600 + 20 * 60) =>
|
114
|
-
{
|
115
|
+
(2 * 3600 + 20 * 60) =>
|
116
|
+
{
|
115
117
|
:micro => '2h20m',
|
116
118
|
:short => '2h 20m',
|
117
119
|
:default => '2 hrs 20 mins',
|
118
120
|
:long => '2 hours 20 minutes',
|
119
121
|
:chrono => '2:20:00'
|
120
122
|
},
|
121
|
-
(6 * 30 * 24 * 3600 + 24 * 3600) =>
|
122
|
-
{
|
123
|
-
:micro => '
|
124
|
-
:short => '
|
123
|
+
(6 * 30 * 24 * 3600 + 24 * 3600) =>
|
124
|
+
{
|
125
|
+
:micro => '6mo1d',
|
126
|
+
:short => '6mo 1d',
|
125
127
|
:default => '6 mos 1 day',
|
126
128
|
:long => '6 months 1 day',
|
127
129
|
:chrono => '6:01:00:00:00' # Yuck. FIXME
|
128
|
-
}
|
130
|
+
},
|
131
|
+
(365 * 24 * 3600 + 24 * 3600 ) =>
|
132
|
+
{
|
133
|
+
:micro => '1y1d',
|
134
|
+
:short => '1y 1d',
|
135
|
+
:default => '1 yr 1 day',
|
136
|
+
:long => '1 year 1 day',
|
137
|
+
:chrono => '1:00:01:00:00:00'
|
138
|
+
},
|
139
|
+
(3 * 365 * 24 * 3600 + 24 * 3600 ) =>
|
140
|
+
{
|
141
|
+
:micro => '3y1d',
|
142
|
+
:short => '3y 1d',
|
143
|
+
:default => '3 yrs 1 day',
|
144
|
+
:long => '3 years 1 day',
|
145
|
+
:chrono => '3:00:01:00:00:00'
|
146
|
+
},
|
129
147
|
}
|
130
|
-
|
148
|
+
|
131
149
|
@exemplars.each do |k, v|
|
132
150
|
v.each do |key, val|
|
133
151
|
it "should properly output a duration of #{k} seconds as #{val} using the #{key.to_s} format option" do
|
@@ -135,12 +153,27 @@ describe ChronicDuration, '.output' do
|
|
135
153
|
end
|
136
154
|
end
|
137
155
|
end
|
138
|
-
|
156
|
+
|
157
|
+
it "should show weeks when needed" do
|
158
|
+
ChronicDuration.output(15*24*60*60, :weeks => true).should =~ /.*wk.*/
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should show the specified number of units if provided" do
|
162
|
+
ChronicDuration.output(4 * 3600 + 60 + 1, units: 2).should == '4 hrs 1 min'
|
163
|
+
ChronicDuration.output(6 * 30 * 24 * 3600 + 24 * 3600 + 3600 + 60 + 1, units: 3, format: :long).should == '6 months 1 day 1 hour'
|
164
|
+
end
|
165
|
+
|
139
166
|
it "should use the default format when the format is not specified" do
|
140
167
|
ChronicDuration.output(2 * 3600 + 20 * 60).should == '2 hrs 20 mins'
|
141
168
|
end
|
142
|
-
|
143
|
-
|
169
|
+
|
170
|
+
@exemplars.each do |seconds,format_spec|
|
171
|
+
format_spec.each do |format,_|
|
172
|
+
it "it should properly output a duration for #{seconds} that parses back to the same thing when using the #{format.to_s} format" do
|
173
|
+
ChronicDuration.parse(ChronicDuration.output(seconds, :format => format)).should == seconds
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
144
177
|
end
|
145
178
|
|
146
179
|
|
@@ -148,37 +181,37 @@ end
|
|
148
181
|
# us in development...
|
149
182
|
|
150
183
|
describe ChronicDuration, "private methods" do
|
151
|
-
|
184
|
+
|
152
185
|
describe ".filter_by_type" do
|
153
|
-
|
186
|
+
|
154
187
|
it "should take a chrono-formatted time like 3:14 and return a human time like 3 minutes 14 seconds" do
|
155
188
|
ChronicDuration.instance_eval("filter_by_type('3:14')").should == '3 minutes 14 seconds'
|
156
189
|
end
|
157
|
-
|
190
|
+
|
158
191
|
it "should take a chrono-formatted time like 12:10:14 and return a human time like 12 hours 10 minutes 14 seconds" do
|
159
192
|
ChronicDuration.instance_eval("filter_by_type('12:10:14')").should == '12 hours 10 minutes 14 seconds'
|
160
193
|
end
|
161
|
-
|
194
|
+
|
162
195
|
it "should return the input if it's not a chrono-formatted time" do
|
163
196
|
ChronicDuration.instance_eval("filter_by_type('4 hours')").should == '4 hours'
|
164
197
|
end
|
165
|
-
|
198
|
+
|
166
199
|
end
|
167
|
-
|
200
|
+
|
168
201
|
describe ".cleanup" do
|
169
|
-
|
202
|
+
|
170
203
|
it "should clean up extraneous words" do
|
171
204
|
ChronicDuration.instance_eval("cleanup('4 days and 11 hours')").should == '4 days 11 hours'
|
172
205
|
end
|
173
|
-
|
206
|
+
|
174
207
|
it "should cleanup extraneous spaces" do
|
175
208
|
ChronicDuration.instance_eval("cleanup(' 4 days and 11 hours')").should == '4 days 11 hours'
|
176
209
|
end
|
177
|
-
|
210
|
+
|
178
211
|
it "should insert spaces where there aren't any" do
|
179
212
|
ChronicDuration.instance_eval("cleanup('4m11.5s')").should == '4 minutes 11.5 seconds'
|
180
213
|
end
|
181
|
-
|
214
|
+
|
182
215
|
end
|
183
|
-
|
184
|
-
end
|
216
|
+
|
217
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChronicDuration do
|
4
|
+
|
5
|
+
describe ".parse" do
|
6
|
+
|
7
|
+
@exemplars = {
|
8
|
+
'1:20' => 60 + 20,
|
9
|
+
'1:20.51' => 60 + 20.51,
|
10
|
+
'4:01:01' => 4 * 3600 + 60 + 1,
|
11
|
+
'3 mins 4 sec' => 3 * 60 + 4,
|
12
|
+
'3 Mins 4 Sec' => 3 * 60 + 4,
|
13
|
+
'three mins four sec' => 3 * 60 + 4,
|
14
|
+
'2 hrs 20 min' => 2 * 3600 + 20 * 60,
|
15
|
+
'2h20min' => 2 * 3600 + 20 * 60,
|
16
|
+
'6 mos 1 day' => 6 * 30 * 24 * 3600 + 24 * 3600,
|
17
|
+
'1 year 6 mos 1 day' => 1 * 31536000 + 6 * 30 * 24 * 3600 + 24 * 3600,
|
18
|
+
'2.5 hrs' => 2.5 * 3600,
|
19
|
+
'47 yrs 6 mos and 4.5d' => 47 * 31536000 + 6 * 30 * 24 * 3600 + 4.5 * 24 * 3600,
|
20
|
+
'two hours and twenty minutes' => 2 * 3600 + 20 * 60,
|
21
|
+
'four hours and forty minutes' => 4 * 3600 + 40 * 60,
|
22
|
+
'four hours, and fourty minutes' => 4 * 3600 + 40 * 60,
|
23
|
+
'3 weeks and, 2 days' => 3600 * 24 * 7 * 3 + 3600 * 24 * 2,
|
24
|
+
'3 weeks, plus 2 days' => 3600 * 24 * 7 * 3 + 3600 * 24 * 2,
|
25
|
+
'3 weeks with 2 days' => 3600 * 24 * 7 * 3 + 3600 * 24 * 2,
|
26
|
+
'1 month' => 3600 * 24 * 30,
|
27
|
+
'2 months' => 3600 * 24 * 30 * 2
|
28
|
+
}
|
29
|
+
|
30
|
+
context "when string can't be parsed" do
|
31
|
+
|
32
|
+
it "returns nil" do
|
33
|
+
ChronicDuration.parse('gobblygoo').should be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when @@raise_exceptions set to true" do
|
37
|
+
|
38
|
+
it "raises with ChronicDuration::DurationParseError" do
|
39
|
+
ChronicDuration.raise_exceptions = true
|
40
|
+
lambda { ChronicDuration.parse('23 gobblygoos') }.should raise_exception(ChronicDuration::DurationParseError)
|
41
|
+
ChronicDuration.raise_exceptions = false
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should return a float if seconds are in decimals" do
|
49
|
+
ChronicDuration.parse('12 mins 3.141 seconds').is_a?(Float).should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return an integer unless the seconds are in decimals" do
|
53
|
+
ChronicDuration.parse('12 mins 3 seconds').is_a?(Integer).should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be able to parse minutes by default" do
|
57
|
+
ChronicDuration.parse('5', :default_unit => "minutes").should == 300
|
58
|
+
end
|
59
|
+
|
60
|
+
@exemplars.each do |k, v|
|
61
|
+
it "parses a duration like #{k}" do
|
62
|
+
ChronicDuration.parse(k).should == v
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.output' do
|
69
|
+
|
70
|
+
@exemplars = {
|
71
|
+
(60 + 20) =>
|
72
|
+
{
|
73
|
+
:micro => '1m20s',
|
74
|
+
:short => '1m 20s',
|
75
|
+
:default => '1 min 20 secs',
|
76
|
+
:long => '1 minute 20 seconds',
|
77
|
+
:chrono => '1:20'
|
78
|
+
},
|
79
|
+
(60 + 20.51) =>
|
80
|
+
{
|
81
|
+
:micro => '1m20.51s',
|
82
|
+
:short => '1m 20.51s',
|
83
|
+
:default => '1 min 20.51 secs',
|
84
|
+
:long => '1 minute 20.51 seconds',
|
85
|
+
:chrono => '1:20.51'
|
86
|
+
},
|
87
|
+
(60 + 20.51928) =>
|
88
|
+
{
|
89
|
+
:micro => '1m20.51928s',
|
90
|
+
:short => '1m 20.51928s',
|
91
|
+
:default => '1 min 20.51928 secs',
|
92
|
+
:long => '1 minute 20.51928 seconds',
|
93
|
+
:chrono => '1:20.51928'
|
94
|
+
},
|
95
|
+
(4 * 3600 + 60 + 1) =>
|
96
|
+
{
|
97
|
+
:micro => '4h1m1s',
|
98
|
+
:short => '4h 1m 1s',
|
99
|
+
:default => '4 hrs 1 min 1 sec',
|
100
|
+
:long => '4 hours 1 minute 1 second',
|
101
|
+
:chrono => '4:01:01'
|
102
|
+
},
|
103
|
+
(2 * 3600 + 20 * 60) =>
|
104
|
+
{
|
105
|
+
:micro => '2h20m',
|
106
|
+
:short => '2h 20m',
|
107
|
+
:default => '2 hrs 20 mins',
|
108
|
+
:long => '2 hours 20 minutes',
|
109
|
+
:chrono => '2:20'
|
110
|
+
},
|
111
|
+
(2 * 3600 + 20 * 60) =>
|
112
|
+
{
|
113
|
+
:micro => '2h20m',
|
114
|
+
:short => '2h 20m',
|
115
|
+
:default => '2 hrs 20 mins',
|
116
|
+
:long => '2 hours 20 minutes',
|
117
|
+
:chrono => '2:20:00'
|
118
|
+
},
|
119
|
+
(6 * 30 * 24 * 3600 + 24 * 3600) =>
|
120
|
+
{
|
121
|
+
:micro => '6mo1d',
|
122
|
+
:short => '6mo 1d',
|
123
|
+
:default => '6 mos 1 day',
|
124
|
+
:long => '6 months 1 day',
|
125
|
+
:chrono => '6:01:00:00:00' # Yuck. FIXME
|
126
|
+
},
|
127
|
+
(365 * 24 * 3600 + 24 * 3600 ) =>
|
128
|
+
{
|
129
|
+
:micro => '1y1d',
|
130
|
+
:short => '1y 1d',
|
131
|
+
:default => '1 yr 1 day',
|
132
|
+
:long => '1 year 1 day',
|
133
|
+
:chrono => '1:00:01:00:00:00'
|
134
|
+
},
|
135
|
+
(3 * 365 * 24 * 3600 + 24 * 3600 ) =>
|
136
|
+
{
|
137
|
+
:micro => '3y1d',
|
138
|
+
:short => '3y 1d',
|
139
|
+
:default => '3 yrs 1 day',
|
140
|
+
:long => '3 years 1 day',
|
141
|
+
:chrono => '3:00:01:00:00:00'
|
142
|
+
},
|
143
|
+
}
|
144
|
+
|
145
|
+
@exemplars.each do |k, v|
|
146
|
+
v.each do |key, val|
|
147
|
+
it "properly outputs a duration of #{k} seconds as #{val} using the #{key.to_s} format option" do
|
148
|
+
ChronicDuration.output(k, :format => key).should == val
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it "returns weeks when needed" do
|
154
|
+
ChronicDuration.output(15*24*60*60, :weeks => true).should =~ /.*wk.*/
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns the specified number of units if provided" do
|
158
|
+
ChronicDuration.output(4 * 3600 + 60 + 1, units: 2).should == '4 hrs 1 min'
|
159
|
+
ChronicDuration.output(6 * 30 * 24 * 3600 + 24 * 3600 + 3600 + 60 + 1, units: 3, format: :long).should == '6 months 1 day 1 hour'
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when the format is not specified" do
|
163
|
+
|
164
|
+
it "uses the default format" do
|
165
|
+
ChronicDuration.output(2 * 3600 + 20 * 60).should == '2 hrs 20 mins'
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
@exemplars.each do |seconds, format_spec|
|
171
|
+
format_spec.each do |format, _|
|
172
|
+
it "outputs a duration for #{seconds} that parses back to the same thing when using the #{format.to_s} format" do
|
173
|
+
ChronicDuration.parse(ChronicDuration.output(seconds, :format => format)).should == seconds
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
describe ".filter_by_type" do
|
181
|
+
|
182
|
+
it "receives a chrono-formatted time like 3:14 and return a human time like 3 minutes 14 seconds" do
|
183
|
+
ChronicDuration.instance_eval("filter_by_type('3:14')").should == '3 minutes 14 seconds'
|
184
|
+
end
|
185
|
+
|
186
|
+
it "receives chrono-formatted time like 12:10:14 and return a human time like 12 hours 10 minutes 14 seconds" do
|
187
|
+
ChronicDuration.instance_eval("filter_by_type('12:10:14')").should == '12 hours 10 minutes 14 seconds'
|
188
|
+
end
|
189
|
+
|
190
|
+
it "returns the input if it's not a chrono-formatted time" do
|
191
|
+
ChronicDuration.instance_eval("filter_by_type('4 hours')").should == '4 hours'
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
describe ".cleanup" do
|
197
|
+
|
198
|
+
it "cleans up extraneous words" do
|
199
|
+
ChronicDuration.instance_eval("cleanup('4 days and 11 hours')").should == '4 days 11 hours'
|
200
|
+
end
|
201
|
+
|
202
|
+
it "cleans up extraneous spaces" do
|
203
|
+
ChronicDuration.instance_eval("cleanup(' 4 days and 11 hours')").should == '4 days 11 hours'
|
204
|
+
end
|
205
|
+
|
206
|
+
it "inserts spaces where there aren't any" do
|
207
|
+
ChronicDuration.instance_eval("cleanup('4m11.5s')").should == '4 minutes 11.5 seconds'
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,121 +1,111 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: chronic_duration
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.9.6
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- hpoydar
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-02-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
17
15
|
name: numerizer
|
18
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
19
17
|
none: false
|
20
|
-
requirements:
|
18
|
+
requirements:
|
21
19
|
- - ~>
|
22
|
-
- !ruby/object:Gem::Version
|
20
|
+
- !ruby/object:Gem::Version
|
23
21
|
version: 0.1.1
|
24
22
|
type: :runtime
|
25
23
|
prerelease: false
|
26
|
-
version_requirements:
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rspec
|
29
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
25
|
none: false
|
31
|
-
requirements:
|
26
|
+
requirements:
|
32
27
|
- - ~>
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version:
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: bundler
|
40
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.1.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
41
33
|
none: false
|
42
|
-
requirements:
|
34
|
+
requirements:
|
43
35
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version:
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 10.0.3
|
46
38
|
type: :development
|
47
39
|
prerelease: false
|
48
|
-
version_requirements:
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: jeweler
|
51
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
41
|
none: false
|
53
|
-
requirements:
|
42
|
+
requirements:
|
54
43
|
- - ~>
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version:
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: rcov
|
62
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 10.0.3
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
63
49
|
none: false
|
64
|
-
requirements:
|
65
|
-
- -
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version:
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.12.0
|
68
54
|
type: :development
|
69
55
|
prerelease: false
|
70
|
-
version_requirements:
|
71
|
-
|
72
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.12.0
|
62
|
+
description: A simple Ruby natural language parser for elapsed time. (For example,
|
63
|
+
4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in
|
64
|
+
seconds. Will return an integer unless you get tricky and need a float. (4 minutes
|
65
|
+
and 13.47 seconds, for example.) The reverse can also be performed via the output
|
66
|
+
method.
|
67
|
+
email:
|
68
|
+
- henry@poydar.com
|
73
69
|
executables: []
|
74
|
-
|
75
70
|
extensions: []
|
76
|
-
|
77
|
-
|
78
|
-
-
|
79
|
-
files:
|
71
|
+
extra_rdoc_files: []
|
72
|
+
files:
|
73
|
+
- .gitignore
|
80
74
|
- Gemfile
|
81
|
-
- Gemfile.lock
|
82
75
|
- MIT-LICENSE
|
83
|
-
- README.
|
76
|
+
- README.md
|
84
77
|
- Rakefile
|
85
|
-
- VERSION
|
86
78
|
- chronic_duration.gemspec
|
87
79
|
- lib/chronic_duration.rb
|
80
|
+
- lib/chronic_duration/version.rb
|
88
81
|
- spec/chronic_duration_spec.rb
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
82
|
+
- spec/lib/chronic_duration_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
84
|
+
homepage: https://github.com/hpoydar/chronic_duration
|
85
|
+
licenses: []
|
93
86
|
post_install_message:
|
94
87
|
rdoc_options: []
|
95
|
-
|
96
|
-
require_paths:
|
88
|
+
require_paths:
|
97
89
|
- lib
|
98
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
91
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
|
105
|
-
- 0
|
106
|
-
version: "0"
|
107
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
97
|
none: false
|
109
|
-
requirements:
|
110
|
-
- -
|
111
|
-
- !ruby/object:Gem::Version
|
112
|
-
version:
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
113
102
|
requirements: []
|
114
|
-
|
115
103
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.
|
104
|
+
rubygems_version: 1.8.23
|
117
105
|
signing_key:
|
118
106
|
specification_version: 3
|
119
|
-
summary: A Ruby natural language parser for elapsed time
|
120
|
-
test_files:
|
107
|
+
summary: A simple Ruby natural language parser for elapsed time
|
108
|
+
test_files:
|
121
109
|
- spec/chronic_duration_spec.rb
|
110
|
+
- spec/lib/chronic_duration_spec.rb
|
111
|
+
- spec/spec_helper.rb
|
data/Gemfile.lock
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
diff-lcs (1.1.2)
|
5
|
-
git (1.2.5)
|
6
|
-
jeweler (1.5.2)
|
7
|
-
bundler (~> 1.0.0)
|
8
|
-
git (>= 1.2.5)
|
9
|
-
rake
|
10
|
-
numerizer (0.1.1)
|
11
|
-
rake (0.8.7)
|
12
|
-
rcov (0.9.9)
|
13
|
-
rspec (2.3.0)
|
14
|
-
rspec-core (~> 2.3.0)
|
15
|
-
rspec-expectations (~> 2.3.0)
|
16
|
-
rspec-mocks (~> 2.3.0)
|
17
|
-
rspec-core (2.3.1)
|
18
|
-
rspec-expectations (2.3.0)
|
19
|
-
diff-lcs (~> 1.1.2)
|
20
|
-
rspec-mocks (2.3.0)
|
21
|
-
|
22
|
-
PLATFORMS
|
23
|
-
ruby
|
24
|
-
|
25
|
-
DEPENDENCIES
|
26
|
-
bundler (~> 1.0.0)
|
27
|
-
jeweler (~> 1.5.2)
|
28
|
-
numerizer (~> 0.1.1)
|
29
|
-
rcov
|
30
|
-
rspec (~> 2.3.0)
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.9.6
|