gitlab_chronic_duration 0.10.6.2 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31c85bafdeb76ec821dee3705c00a9755f41a82f49a3226b0955b40b6c6093be
4
- data.tar.gz: e6c7a5ee5f8ed8e8668ae09891b3b21c6770bb2a8cd2639c4ea7dbe2635be46f
3
+ metadata.gz: 90ed911722678aa8c57973bd8cf733877d32bd06b0e313764502100bd0e36bf7
4
+ data.tar.gz: 5a5afd28caceefa29332d8774a161b811a1340344fdff23a33cd33f7d91aaaea
5
5
  SHA512:
6
- metadata.gz: 4ee3b0723ac970588440c226025a1fbd026ffe7304e203304bfee1445794dae1f9d660d49653c94b2b714dcf2f04d899ec0bc0554c683c8cf2e67860cc3db740
7
- data.tar.gz: e7950ea62b28e6c6cfe2f3a877b46a80b7a5281d5196557e8a86f91093f4c5f15fdb94d1afe26b248b391972c2e033dae2c15f94c2eb71aba784d63fd55783f9
6
+ metadata.gz: '085d3ef7649df9ff93e215b41cea7d77739c415c9295f201a5e005da90c52309d395459bf0543512e729c0feb73a4520d4123d7250191888212f6c12f7f2c0d8'
7
+ data.tar.gz: 374eaf5cfee394c835a28bad82214de21a921a4cbc11a99f58844e43b7f240c804f757b941294924927a7b88a33e3925a44c86e6f8defc893c0533e00bc969e2
data/.gitlab-ci.yml CHANGED
@@ -1,12 +1,17 @@
1
- image: "ruby:2.5"
2
-
3
- before_script:
4
- - ruby -v
5
- - which ruby
6
- - gem install bundler
7
- - bundle install --jobs $(nproc) "${FLAGS[@]}"
1
+ .default:
2
+ image: "ruby:${RUBY_VERSION}"
3
+ before_script:
4
+ - ruby -v
5
+ - which ruby
6
+ - gem install bundler
7
+ - bundle install --jobs $(nproc) "${FLAGS[@]}"
8
8
 
9
9
  rspec:
10
+ extends:
11
+ - .default
10
12
  stage: test
11
13
  script:
12
14
  - bundle exec rspec
15
+ parallel:
16
+ matrix:
17
+ - RUBY_VERSION: ['2.7', '3.0', '3.1', '3.2']
data/README.md CHANGED
@@ -8,7 +8,7 @@ The reverse can also be accomplished with the output method. So pass in seconds
8
8
 
9
9
  ## Usage
10
10
 
11
- >> require 'chronic_duration'
11
+ >> require 'gitlab_chronic_duration'
12
12
  => true
13
13
  >> ChronicDuration.parse('4 minutes and 30 seconds')
14
14
  => 270
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.email = ["henry@poydar.com"]
12
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
13
  gem.summary = %q{A simple Ruby natural language parser for elapsed time}
14
- gem.homepage = "https://gitlab.com/gitlab-org/gitlab-chronic-duration"
14
+ gem.homepage = "https://gitlab.com/gitlab-org/ruby/gems/gitlab-chronic-duration"
15
15
  gem.license = "MIT"
16
16
 
17
17
  gem.files = `git ls-files`.split($/)
@@ -22,7 +22,7 @@ Gem::Specification.new do |gem|
22
22
  gem.add_runtime_dependency "numerizer", "~> 0.2"
23
23
 
24
24
  gem.add_development_dependency "rake", "~> 10.0.3"
25
- gem.add_development_dependency "rspec", "~> 2.12.0"
25
+ gem.add_development_dependency "rspec", "~> 3.12"
26
26
 
27
27
 
28
28
  end
@@ -1,5 +1,3 @@
1
1
  module ChronicDuration
2
- # '0.10.6' is the versioning used in 'https://github.com/henrypoydar/chronic_duration',
3
- # we are adding revision part to highlight GitLab changes, e.g. '0.10.6.N'
4
- VERSION = '0.10.6.2'.freeze
2
+ VERSION = '0.11.0'.freeze
5
3
  end
@@ -1,3 +1,7 @@
1
+ # NOTE:
2
+ # Changes to this file should be kept in sync with
3
+ # https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/chronic_duration.js.
4
+
1
5
  require 'numerizer' unless defined?(Numerizer)
2
6
 
3
7
  module ChronicDuration
@@ -42,7 +46,8 @@ module ChronicDuration
42
46
  # return an integer (or float, if fractions of a
43
47
  # second are input)
44
48
  def parse(string, opts = {})
45
- result = calculate_from_words(cleanup(string), opts)
49
+ use_complete_matcher = opts.fetch(:use_complete_matcher, false)
50
+ result = calculate_from_words(cleanup(string, use_complete_matcher), opts)
46
51
  (!opts[:keep_zero] and result == 0) ? nil : result
47
52
  end
48
53
 
@@ -184,9 +189,9 @@ private
184
189
  val
185
190
  end
186
191
 
187
- def cleanup(string)
192
+ def cleanup(string, use_complete_matcher = false)
188
193
  res = string.downcase
189
- res = filter_by_type(Numerizer.numerize(res))
194
+ res = filter_by_type(Numerizer.numerize(res), use_complete_matcher)
190
195
  res = res.gsub(float_matcher) {|n| " #{n} "}.squeeze(' ').strip
191
196
  res = filter_through_white_list(res)
192
197
  end
@@ -218,9 +223,11 @@ private
218
223
  end
219
224
 
220
225
  # Parse 3:41:59 and return 3 hours 41 minutes 59 seconds
221
- def filter_by_type(string)
226
+ def filter_by_type(string, use_complete_matcher = false)
222
227
  chrono_units_list = duration_units_list.reject {|v| v == "weeks"}
223
- if string.gsub(' ', '') =~ /#{float_matcher}(:#{float_matcher})+/
228
+ matcher = use_complete_matcher ? time_matcher : /#{float_matcher}(:#{float_matcher})+/
229
+
230
+ if string.gsub(' ', '') =~ matcher
224
231
  res = []
225
232
  string.gsub(' ', '').split(':').reverse.each_with_index do |v,k|
226
233
  return unless chrono_units_list[k]
@@ -233,6 +240,10 @@ private
233
240
  res
234
241
  end
235
242
 
243
+ def time_matcher
244
+ /^[0-9]+:[0-9]+(:[0-9]+){0,4}(\.[0-9]*)?$/
245
+ end
246
+
236
247
  def float_matcher
237
248
  /[0-9]*\.?[0-9]+/
238
249
  end
@@ -1,3 +1,7 @@
1
+ # NOTE:
2
+ # Changes to this file should be kept in sync with
3
+ # https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/frontend/chronic_duration_spec.js.
4
+
1
5
  require 'spec_helper'
2
6
 
3
7
  describe ChronicDuration do
@@ -34,11 +38,11 @@ describe ChronicDuration do
34
38
  context "when string can't be parsed" do
35
39
 
36
40
  it "returns nil" do
37
- ChronicDuration.parse('gobblygoo').should be_nil
41
+ expect(ChronicDuration.parse('gobblygoo')).to be_nil
38
42
  end
39
43
 
40
44
  it "cannot parse zero" do
41
- ChronicDuration.parse('0').should be_nil
45
+ expect(ChronicDuration.parse('0')).to be_nil
42
46
  end
43
47
 
44
48
  context "when @@raise_exceptions set to true" do
@@ -54,47 +58,47 @@ describe ChronicDuration do
54
58
  end
55
59
 
56
60
  it "should return zero if the string parses as zero and the keep_zero option is true" do
57
- ChronicDuration.parse('0', :keep_zero => true).should == 0
61
+ expect(ChronicDuration.parse('0', :keep_zero => true)).to eq(0)
58
62
  end
59
63
 
60
64
  it "should return a float if seconds are in decimals" do
61
- ChronicDuration.parse('12 mins 3.141 seconds').is_a?(Float).should be_true
65
+ expect(ChronicDuration.parse('12 mins 3.141 seconds')).to be_a(Float)
62
66
  end
63
67
 
64
68
  it "should return an integer unless the seconds are in decimals" do
65
- ChronicDuration.parse('12 mins 3 seconds').is_a?(Integer).should be_true
69
+ expect(ChronicDuration.parse('12 mins 3 seconds')).to be_a(Integer)
66
70
  end
67
71
 
68
72
  it "should be able to parse minutes by default" do
69
- ChronicDuration.parse('5', :default_unit => "minutes").should == 300
73
+ expect(ChronicDuration.parse('5', :default_unit => "minutes")).to eq(300)
70
74
  end
71
75
 
72
76
  @exemplars.each do |k, v|
73
77
  it "parses a duration like #{k}" do
74
- ChronicDuration.parse(k).should == v
78
+ expect(ChronicDuration.parse(k)).to eq(v)
75
79
  end
76
80
  end
77
81
 
78
82
  context 'with :hours_per_day and :days_per_month params' do
79
83
  it 'uses provided :hours_per_day' do
80
- ChronicDuration.parse('1d', hours_per_day: 24).should == 24 * 60 * 60
81
- ChronicDuration.parse('1d', hours_per_day: 8).should == 8 * 60 * 60
84
+ expect(ChronicDuration.parse('1d', hours_per_day: 24)).to eq(24 * 60 * 60)
85
+ expect(ChronicDuration.parse('1d', hours_per_day: 8)).to eq(8 * 60 * 60)
82
86
  end
83
87
 
84
88
  it 'uses provided :days_per_month' do
85
- ChronicDuration.parse('1mo', days_per_month: 30).should == 30 * 24 * 60 * 60
86
- ChronicDuration.parse('1mo', days_per_month: 20).should == 20 * 24 * 60 * 60
89
+ expect(ChronicDuration.parse('1mo', days_per_month: 30)).to eq(30 * 24 * 60 * 60)
90
+ expect(ChronicDuration.parse('1mo', days_per_month: 20)).to eq(20 * 24 * 60 * 60)
87
91
 
88
- ChronicDuration.parse('1w', days_per_month: 30).should == 7 * 24 * 60 * 60
89
- ChronicDuration.parse('1w', days_per_month: 20).should == 5 * 24 * 60 * 60
92
+ expect(ChronicDuration.parse('1w', days_per_month: 30)).to eq(7 * 24 * 60 * 60)
93
+ expect(ChronicDuration.parse('1w', days_per_month: 20)).to eq(5 * 24 * 60 * 60)
90
94
  end
91
95
 
92
96
  it 'uses provided both :hours_per_day and :days_per_month' do
93
- ChronicDuration.parse('1mo', days_per_month: 30, hours_per_day: 24).should == 30 * 24 * 60 * 60
94
- ChronicDuration.parse('1mo', days_per_month: 20, hours_per_day: 8).should == 20 * 8 * 60 * 60
97
+ expect(ChronicDuration.parse('1mo', days_per_month: 30, hours_per_day: 24)).to eq(30 * 24 * 60 * 60)
98
+ expect(ChronicDuration.parse('1mo', days_per_month: 20, hours_per_day: 8)).to eq(20 * 8 * 60 * 60)
95
99
 
96
- ChronicDuration.parse('1w', days_per_month: 30, hours_per_day: 24).should == 7 * 24 * 60 * 60
97
- ChronicDuration.parse('1w', days_per_month: 20, hours_per_day: 8).should == 5 * 8 * 60 * 60
100
+ expect(ChronicDuration.parse('1w', days_per_month: 30, hours_per_day: 24)).to eq(7 * 24 * 60 * 60)
101
+ expect(ChronicDuration.parse('1w', days_per_month: 20, hours_per_day: 8)).to eq(5 * 8 * 60 * 60)
98
102
  end
99
103
  end
100
104
  end
@@ -187,7 +191,7 @@ describe ChronicDuration do
187
191
  @exemplars.each do |k, v|
188
192
  v.each do |key, val|
189
193
  it "properly outputs a duration of #{k} seconds as #{val} using the #{key.to_s} format option" do
190
- ChronicDuration.output(k, :format => key).should == val
194
+ expect(ChronicDuration.output(k, :format => key)).to eq(val)
191
195
  end
192
196
  end
193
197
  end
@@ -214,83 +218,94 @@ describe ChronicDuration do
214
218
  @keep_zero_exemplars.each do |k, v|
215
219
  v.each do |key, val|
216
220
  it "should properly output a duration of 0 seconds as #{val.nil? ? "nil" : val} using the #{key.to_s} format option, if the keep_zero option is #{k.to_s}" do
217
- ChronicDuration.output(0, :format => key, :keep_zero => k).should == val
221
+ expect(ChronicDuration.output(0, :format => key, :keep_zero => k)).to eq(val)
218
222
  end
219
223
  end
220
224
  end
221
225
 
222
226
  it "returns weeks when needed" do
223
- ChronicDuration.output(45*24*60*60, :weeks => true).should =~ /.*wk.*/
227
+ expect(ChronicDuration.output(45*24*60*60, :weeks => true)).to match(/.*wk.*/)
224
228
  end
225
229
 
226
230
  it "returns hours and minutes only when :hours_only option specified" do
227
- ChronicDuration.output(395*24*60*60 + 15*60, :limit_to_hours => true).should == '9480 hrs 15 mins'
231
+ expect(ChronicDuration.output(395*24*60*60 + 15*60, :limit_to_hours => true)).to eq('9480 hrs 15 mins')
228
232
  end
229
233
 
230
234
  context 'with :hours_per_day and :days_per_month params' do
231
235
  it 'uses provided :hours_per_day' do
232
- ChronicDuration.output(24 * 60 * 60, hours_per_day: 24).should == '1 day'
233
- ChronicDuration.output(24 * 60 * 60, hours_per_day: 8).should == '3 days'
236
+ expect(ChronicDuration.output(24 * 60 * 60, hours_per_day: 24)).to eq('1 day')
237
+ expect(ChronicDuration.output(24 * 60 * 60, hours_per_day: 8)).to eq('3 days')
234
238
  end
235
239
 
236
240
  it 'uses provided :days_per_month' do
237
- ChronicDuration.output(7 * 24 * 60 * 60, weeks: true, days_per_month: 30).should == '1 wk'
238
- ChronicDuration.output(7 * 24 * 60 * 60, weeks: true, days_per_month: 20).should == '1 wk 2 days'
241
+ expect(ChronicDuration.output(7 * 24 * 60 * 60, weeks: true, days_per_month: 30)).to eq('1 wk')
242
+ expect(ChronicDuration.output(7 * 24 * 60 * 60, weeks: true, days_per_month: 20)).to eq('1 wk 2 days')
239
243
  end
240
244
 
241
245
  it 'uses provided both :hours_per_day and :days_per_month' do
242
- ChronicDuration.output(7 * 24 * 60 * 60, weeks: true, days_per_month: 30, hours_per_day: 24).should == '1 wk'
243
- ChronicDuration.output(5 * 8 * 60 * 60, weeks: true, days_per_month: 20, hours_per_day: 8).should == '1 wk'
246
+ expect(ChronicDuration.output(7 * 24 * 60 * 60, weeks: true, days_per_month: 30, hours_per_day: 24)).to eq('1 wk')
247
+ expect(ChronicDuration.output(5 * 8 * 60 * 60, weeks: true, days_per_month: 20, hours_per_day: 8)).to eq('1 wk')
244
248
  end
245
249
 
246
250
  it 'uses provided params alonside with :weeks when converting to months' do
247
- ChronicDuration.output(30 * 24 * 60 * 60, days_per_month: 30, hours_per_day: 24).should == '1 mo'
248
- ChronicDuration.output(30 * 24 * 60 * 60, days_per_month: 30, hours_per_day: 24, weeks: true).should == '1 mo 2 days'
251
+ expect(ChronicDuration.output(30 * 24 * 60 * 60, days_per_month: 30, hours_per_day: 24)).to eq('1 mo')
252
+ expect(ChronicDuration.output(30 * 24 * 60 * 60, days_per_month: 30, hours_per_day: 24, weeks: true)).to eq('1 mo 2 days')
249
253
 
250
- ChronicDuration.output(20 * 8 * 60 * 60, days_per_month: 20, hours_per_day: 8).should == '1 mo'
251
- ChronicDuration.output(20 * 8 * 60 * 60, days_per_month: 20, hours_per_day: 8, weeks: true).should == '1 mo'
254
+ expect(ChronicDuration.output(20 * 8 * 60 * 60, days_per_month: 20, hours_per_day: 8)).to eq('1 mo')
255
+ expect(ChronicDuration.output(20 * 8 * 60 * 60, days_per_month: 20, hours_per_day: 8, weeks: true)).to eq('1 mo')
252
256
  end
253
257
  end
254
258
 
255
259
  it "returns the specified number of units if provided" do
256
- ChronicDuration.output(4 * 3600 + 60 + 1, units: 2).should == '4 hrs 1 min'
257
- ChronicDuration.output(6 * 30 * 24 * 3600 + 24 * 3600 + 3600 + 60 + 1, units: 3, format: :long).should == '6 months 1 day 1 hour'
260
+ expect(ChronicDuration.output(4 * 3600 + 60 + 1, units: 2)).to eq('4 hrs 1 min')
261
+ expect(ChronicDuration.output(6 * 30 * 24 * 3600 + 24 * 3600 + 3600 + 60 + 1, units: 3, format: :long)).to eq('6 months 1 day 1 hour')
258
262
  end
259
263
 
260
264
  context "when the format is not specified" do
261
265
 
262
266
  it "uses the default format" do
263
- ChronicDuration.output(2 * 3600 + 20 * 60).should == '2 hrs 20 mins'
267
+ expect(ChronicDuration.output(2 * 3600 + 20 * 60)).to eq('2 hrs 20 mins')
264
268
  end
265
269
 
266
270
  end
267
271
 
268
272
  @exemplars.each do |seconds, format_spec|
269
273
  format_spec.each do |format, _|
270
- it "outputs a duration for #{seconds} that parses back to the same thing when using the #{format.to_s} format" do
271
- ChronicDuration.parse(ChronicDuration.output(seconds, :format => format)).should == seconds
274
+ context 'when using the legacy time matcher' do
275
+ it "outputs a duration for #{seconds} that parses back to the same thing when using the #{format} format" do
276
+ expect(ChronicDuration.parse(
277
+ ChronicDuration.output(seconds, format: format, use_complete_matcher: false)
278
+ )).to eq(seconds)
279
+ end
280
+ end
281
+
282
+ context 'when using the new time matcher' do
283
+ it "outputs a duration for #{seconds} that parses back to the same thing when using the #{format} format" do
284
+ expect(ChronicDuration.parse(
285
+ ChronicDuration.output(seconds, format: format, use_complete_matcher: true)
286
+ )).to eq(seconds)
287
+ end
272
288
  end
273
289
  end
274
290
  end
275
291
 
276
292
  it "uses user-specified joiner if provided" do
277
- ChronicDuration.output(2 * 3600 + 20 * 60, joiner: ', ').should == '2 hrs, 20 mins'
293
+ expect(ChronicDuration.output(2 * 3600 + 20 * 60, joiner: ', ')).to eq('2 hrs, 20 mins')
278
294
  end
279
-
280
295
  end
281
296
 
282
297
  describe ".filter_by_type" do
283
298
 
284
299
  it "receives a chrono-formatted time like 3:14 and return a human time like 3 minutes 14 seconds" do
285
- ChronicDuration.instance_eval("filter_by_type('3:14')").should == '3 minutes 14 seconds'
300
+ expect(ChronicDuration.instance_eval("filter_by_type('3:14')")).to eq('3 minutes 14 seconds')
286
301
  end
287
302
 
288
303
  it "receives chrono-formatted time like 12:10:14 and return a human time like 12 hours 10 minutes 14 seconds" do
289
- ChronicDuration.instance_eval("filter_by_type('12:10:14')").should == '12 hours 10 minutes 14 seconds'
304
+ expect(ChronicDuration.instance_eval("filter_by_type('12:10:14')")).to eq('12 hours 10 minutes 14 seconds')
290
305
  end
291
306
 
292
307
  it "returns the input if it's not a chrono-formatted time" do
293
- ChronicDuration.instance_eval("filter_by_type('4 hours')").should == '4 hours'
308
+ expect(ChronicDuration.instance_eval("filter_by_type('4 hours')")).to eq('4 hours')
294
309
  end
295
310
 
296
311
  end
@@ -298,15 +313,15 @@ describe ChronicDuration do
298
313
  describe ".cleanup" do
299
314
 
300
315
  it "cleans up extraneous words" do
301
- ChronicDuration.instance_eval("cleanup('4 days and 11 hours')").should == '4 days 11 hours'
316
+ expect(ChronicDuration.instance_eval("cleanup('4 days and 11 hours')")).to eq('4 days 11 hours')
302
317
  end
303
318
 
304
319
  it "cleans up extraneous spaces" do
305
- ChronicDuration.instance_eval("cleanup(' 4 days and 11 hours')").should == '4 days 11 hours'
320
+ expect(ChronicDuration.instance_eval("cleanup(' 4 days and 11 hours')")).to eq('4 days 11 hours')
306
321
  end
307
322
 
308
323
  it "inserts spaces where there aren't any" do
309
- ChronicDuration.instance_eval("cleanup('4m11.5s')").should == '4 minutes 11.5 seconds'
324
+ expect(ChronicDuration.instance_eval("cleanup('4m11.5s')")).to eq('4 minutes 11.5 seconds')
310
325
  end
311
326
 
312
327
  end
@@ -324,8 +339,8 @@ describe ChronicDuration do
324
339
 
325
340
  it "should parse knowing the work week" do
326
341
  week = ChronicDuration.parse('5d')
327
- ChronicDuration.parse('40h').should == week
328
- ChronicDuration.parse('1w').should == week
342
+ expect(ChronicDuration.parse('40h')).to eq(week)
343
+ expect(ChronicDuration.parse('1w')).to eq(week)
329
344
  end
330
345
  end
331
346
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab_chronic_duration
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.6.2
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hpoydar
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-24 00:00:00.000000000 Z
11
+ date: 2023-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numerizer
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.12.0
47
+ version: '3.12'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.12.0
54
+ version: '3.12'
55
55
  description: A simple Ruby natural language parser for elapsed time. (For example,
56
56
  4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in
57
57
  seconds. Will return an integer unless you get tricky and need a float. (4 minutes
@@ -75,11 +75,11 @@ files:
75
75
  - lib/gitlab_chronic_duration.rb
76
76
  - spec/lib/chronic_duration_spec.rb
77
77
  - spec/spec_helper.rb
78
- homepage: https://gitlab.com/gitlab-org/gitlab-chronic-duration
78
+ homepage: https://gitlab.com/gitlab-org/ruby/gems/gitlab-chronic-duration
79
79
  licenses:
80
80
  - MIT
81
81
  metadata: {}
82
- post_install_message:
82
+ post_install_message:
83
83
  rdoc_options: []
84
84
  require_paths:
85
85
  - lib
@@ -94,8 +94,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
96
  requirements: []
97
- rubygems_version: 3.0.3
98
- signing_key:
97
+ rubygems_version: 3.4.19
98
+ signing_key:
99
99
  specification_version: 4
100
100
  summary: A simple Ruby natural language parser for elapsed time
101
101
  test_files: