dotiw 5.3.3 → 5.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 156f786ed11b28af2e890b6612fb07fb09bd462dc818a5bb8bb9075a518044d7
4
- data.tar.gz: ca01c5a48869011c7c1fe9f08cf8c6ad953920b4ea5bc4dd26e21850131b6363
3
+ metadata.gz: 32864f97b3b06dc77f8c793e11a5b17b1d2af506bdfac0c559354f3e4eef7998
4
+ data.tar.gz: 20efed42fb0802a836f078f2791d78e7b863005b73780243ad4867bbf653103e
5
5
  SHA512:
6
- metadata.gz: 807d4628412b8d810c072ea5cf4e10ed2cb7e280bdeaeb1b65906f1e203bd1155c5a7457d21d4c8c8c112a5a7d0a9b9b9a3c9ff5f1100d6ff0a255f64380a1f3
7
- data.tar.gz: 78c14c9c5ea09eb378a380fe686672e925665fdebd9f75096a5cdecc1f9d8497d9cf7839a8cad4dd9d84e4938441e1380c076ecb3ccbf0a24359aa70993da9a2
6
+ metadata.gz: 6bb97a0d7bc860b57432dc81cb3d8a7921c6364c5271db648d30984164f26d6f4003e21de28252f958294960df1b0270cc4fbf83ae7602be23096829404ee2fe
7
+ data.tar.gz: e2d4f70428937b7e5c409666612dd7aefbe63e71d884a3738b240c222fc2f36a8df7a66b83fa4d52fef96cd27e7edd3a9fdecb15e497fa46853e9b3922f83663
@@ -1,12 +1,6 @@
1
1
  name: Ruby
2
2
 
3
- on:
4
- push:
5
- branches:
6
- - master
7
- pull_request:
8
- branches:
9
- - master
3
+ on: [push, pull_request]
10
4
 
11
5
  jobs:
12
6
  build:
@@ -15,19 +9,26 @@ jobs:
15
9
  fail-fast: false
16
10
  matrix:
17
11
  include:
18
- - ruby-version: 2.5
19
- - ruby-version: 2.6
20
- - ruby-version: 2.4
21
- bundler-version: 1.17.3
22
- gemfile: gemfiles/rails_4.gemfile
23
- - ruby-version: 2.6
12
+ - ruby-version: 3.4
13
+ - ruby-version: 3.3
14
+ - ruby-version: 3.2
15
+ - ruby-version: 3.1
16
+ - ruby-version: 3.0
17
+ - ruby-version: 2.7
18
+ - ruby-version: 2.7
24
19
  gemfile: gemfiles/rails_5.0.gemfile
25
- - ruby-version: 2.6
20
+ - ruby-version: 2.7
26
21
  gemfile: gemfiles/rails_5.1.gemfile
27
- - ruby-version: 2.6
22
+ - ruby-version: 2.7
28
23
  gemfile: gemfiles/rails_5.2.gemfile
29
- - ruby-version: 2.6
24
+ - ruby-version: 3.4
30
25
  gemfile: gemfiles/rails_6.0.gemfile
26
+ - ruby-version: 3.4
27
+ gemfile: gemfiles/rails_7.0.gemfile
28
+ - ruby-version: 3.4
29
+ gemfile: gemfiles/rails_7.1.gemfile
30
+ - ruby-version: 3.4
31
+ gemfile: gemfiles/rails_7.2.gemfile
31
32
  steps:
32
33
  - uses: actions/checkout@v2
33
34
  - name: Set up Ruby
data/Appraisals CHANGED
@@ -1,7 +1,3 @@
1
- appraise 'rails_4' do
2
- gem 'rails', '~> 4.0'
3
- end
4
-
5
1
  appraise 'rails_5.0' do
6
2
  gem 'rails', '~> 5.0.0'
7
3
  end
@@ -17,3 +13,15 @@ end
17
13
  appraise 'rails_6.0' do
18
14
  gem 'rails', '~> 6.0.0'
19
15
  end
16
+
17
+ appraise 'rails_7.0' do
18
+ gem 'rails', '~> 7.0.0'
19
+ end
20
+
21
+ appraise 'rails_7.1' do
22
+ gem 'rails', '~> 7.1.0'
23
+ end
24
+
25
+ appraise 'rails_7.2' do
26
+ gem 'rails', '~> 7.2.0'
27
+ end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 5.4.0 (Next)
2
+
3
+ * [#131](https://github.com/radar/distance_of_time_in_words/pull/131): Deprecates `highest_measure_only`. Adds alternate form of `highest_measures` option to permit rounding up whatever part of the duration was previously silently discarded - [@seansfkelley](https://github.com/seansfkelley).
4
+ * [#133](https://github.com/radar/distance_of_time_in_words/pull/133): Test on Ruby 3.0 and 3.1 - [@dblock](https://github.com/dblock).
5
+ * [#134](https://github.com/radar/distance_of_time_in_words/pull/134): Add support for Dzongkha, the National language of Bhutan - [@KinWang-2013](https://github.com/KinWang-2013).
6
+ * [#135](https://github.com/radar/distance_of_time_in_words/pull/135): Add support for Ruby 2.7 and 3.2, removed support for ruby 2.4, 2.5, 2.6 and Rails 4 - [@KinWang-2013](https://github.com/KinWang-2013).
7
+ * [#136](https://github.com/radar/distance_of_time_in_words/pull/136): Add support for Rails 7 - [@KinWang-2013](https://github.com/KinWang-2013).
8
+ * [#139](https://github.com/radar/distance_of_time_in_words/pull/139): Fix bug with pluralization of Russian translations for numbers ending in 1 - [bitberry-dev](https://github.com/bitberry-dev).
9
+ * Your contribution here.
10
+
1
11
  ## 5.3.3 (2022/04/25)
2
12
 
3
13
  * [#128](https://github.com/radar/distance_of_time_in_words/pull/128): Adds support for numeric values for both the `from_time` and `to_time` arguments in the `#distance_of_time_in_words` helper - [@bjedrocha](https://github.com/bjedrocha).
data/CODEOWNERS ADDED
@@ -0,0 +1,2 @@
1
+ @radar
2
+ *.gemspec @radar
data/README.markdown CHANGED
@@ -164,6 +164,8 @@ Culling a whole group of measurements of time:
164
164
 
165
165
  #### :highest\_measure\_only
166
166
 
167
+ > **Deprecated**. Use `highest_measures: 1` instead.
168
+
167
169
  For times when Rails `distance_of_time_in_words` is not precise enough and `DOTIW` is too precise. For instance, if you only want to know the highest time part (measure) that elapsed between two dates.
168
170
 
169
171
  ```ruby
@@ -189,6 +191,24 @@ When you want variable precision from `DOTIW`:
189
191
  => "1 hour and 1 minute"
190
192
  ```
191
193
 
194
+ You can also specify what to do with the extra time with the `remainder` option:
195
+
196
+ ```ruby
197
+ >> distance_of_time_in_words(Time.now, Time.now + 1.hour + 1.minute + 1.second, true, highest_measures: { max: 2, remainder: :ceiling })
198
+ => "1 hour and 2 minutes"
199
+ ```
200
+
201
+ Valid options for `remainder` are `:floor` (default), `:ceiling` and `:round`. Note that `:round` is best-effort and makes some simplifying assumptions:
202
+
203
+ ```ruby
204
+ # Only the next-largest unit is examined, which can unexpectedly round down in some situations.
205
+ >> distance_of_time_in_words(Time.now, Time.now + 1.week + 3.days + 23.hours, true, highest_measures: { remainder: :round })
206
+ => "1 week"
207
+ # The variability of some measures (like months) is ignored and the shortest duration of that measure is used.
208
+ >> distance_of_time_in_words(Time.now, Time.now + 1.month + 14.days, true, highest_measures: { remainder: :round })
209
+ => "2 months"
210
+ ```
211
+
192
212
  #### :words_connector
193
213
 
194
214
  This is an option for `to_sentence`, defaults to ', '.
data/dotiw.gemspec CHANGED
@@ -27,6 +27,9 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'rake'
28
28
  s.add_development_dependency 'rspec', '~> 3.0'
29
29
  s.add_development_dependency 'tzinfo', '~> 1.2.7'
30
+ s.add_development_dependency 'mutex_m'
31
+ s.add_development_dependency 'base64'
32
+ s.add_development_dependency 'bigdecimal'
30
33
 
31
34
  s.files = `git ls-files`.split("\n")
32
35
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -4,6 +4,7 @@
4
4
 
5
5
  source 'http://rubygems.org'
6
6
 
7
- gem 'rails', '~> 4.0'
7
+ gem 'rails', '~> 7.0.0'
8
+ gem 'tzinfo', '~> 2.0'
8
9
 
9
10
  gemspec path: '../'
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was generated by Appraisal
4
+
5
+ source 'http://rubygems.org'
6
+
7
+ gem 'rails', '~> 7.1.0'
8
+ gem 'tzinfo', '~> 2.0'
9
+
10
+
11
+ gemspec path: '../'
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was generated by Appraisal
4
+
5
+ source 'http://rubygems.org'
6
+
7
+ gem 'rails', '~> 7.2.0'
8
+ gem 'tzinfo', '~> 2.0'
9
+
10
+
11
+ gemspec path: '../'
@@ -0,0 +1,60 @@
1
+ dz:
2
+ datetime:
3
+ dotiw:
4
+ seconds:
5
+ one: སྐར་ཆ་ ༡
6
+ other: "སྐར་ཆ་ %{count}"
7
+ minutes:
8
+ one: སྐར་མ་ ༡
9
+ other: "སྐར་མ་ %{count}"
10
+ hours:
11
+ one: ཆུ་ཚོད་ ༡
12
+ other: "ཆུ་ཚོད་ %{count}"
13
+ days:
14
+ one: ཉིནམ་ ༡
15
+ other: "ཉིནམ་ %{count}"
16
+ weeks:
17
+ one: བདུན༌ཕྲག་ ༡
18
+ other: "བདུན༌ཕྲག་ %{count}"
19
+ months:
20
+ one: ཟླཝ་ ༡
21
+ other: "ཟླཝ་ %{count}"
22
+ years:
23
+ one: ལོ་ ༡
24
+ other: "ལོ་ %{count}"
25
+ less_than_x: "%{distance} ་ལས་ཉུངམ་"
26
+ dotiw_compact:
27
+ seconds:
28
+ one: སྐར་ཆ་ ༡
29
+ other: "སྐར་ཆ་ %{count}"
30
+ minutes:
31
+ one: སྐར་མ་ ༡
32
+ other: "སྐར་མ་ %{count}"
33
+ hours:
34
+ one: ཆུ་ཚོད་ ༡
35
+ other: "ཆུ་ཚོད་ %{count}"
36
+ days:
37
+ one: ཉིནམ་ ༡
38
+ other: "ཉིནམ་ %{count}"
39
+ weeks:
40
+ one: བདུན༌ཕྲག་ ༡
41
+ other: "བདུན༌ཕྲག་ %{count}"
42
+ months:
43
+ one: ཟླཝ་ ༡
44
+ other: "ཟླཝ་ %{count}"
45
+ years:
46
+ one: ལོ་ ༡
47
+ other: "ལོ་ %{count}"
48
+ less_than_x: "%{distance} ་ལས་ཉུངམ"
49
+ words_connector: ""
50
+ two_words_connector: " དང་ "
51
+ last_word_connector: " དང་ "
52
+ about_x_years:
53
+ one: ལོ་ ༡ ་དེ་ཅིག
54
+ any: "ལོ་ %{count} ་དེ་ཅིག"
55
+ over_x_years:
56
+ one: "ལོ་ ༡ ་ལས་ལྷགཔ་ཅིག"
57
+ other: "ལོ་ %{count} ་ལས་ལྷགཔ་ཅིག"
58
+ almost_x_years:
59
+ one: ལོ་ ༡ ་མ་ལྷགཔ་ཅིག
60
+ any: "ལོ་ %{count} ་མ་ལྷགཔ་ཅིག"
@@ -39,22 +39,22 @@ ru:
39
39
  less_than_x: "меньше, чем %{distance}"
40
40
  dotiw_compact:
41
41
  seconds:
42
- one: 1с
42
+ one: "%{count}с"
43
43
  other: "%{count}с"
44
44
  minutes:
45
- one: 1м
45
+ one: "%{count}м"
46
46
  other: "%{count}м"
47
47
  hours:
48
- one: 1ч
48
+ one: "%{count}ч"
49
49
  other: "%{count}ч"
50
50
  days:
51
- one: 1д
51
+ one: "%{count}д"
52
52
  other: "%{count}д"
53
53
  weeks:
54
- one: 1н
54
+ one: "%{count}н"
55
55
  other: "%{count}н"
56
56
  months:
57
- one: 1ме
57
+ one: "%{count}ме"
58
58
  other: "%{count}ме"
59
59
  years:
60
60
  one: "%{count}г"
@@ -66,11 +66,11 @@ ru:
66
66
  two_words_connector: ""
67
67
  last_word_connector: ""
68
68
  about_x_years:
69
- one: ~1г
69
+ one: "~%{count}г"
70
70
  any: "~%{count}г"
71
71
  over_x_years:
72
- one: ">1г"
72
+ one: ">%{count}г"
73
73
  other: ">%{count}г"
74
74
  almost_x_years:
75
- one: ~1г
75
+ one: "~%{count}г"
76
76
  any: "~%{count}г"
data/lib/dotiw/methods.rb CHANGED
@@ -44,6 +44,31 @@ module DOTIW
44
44
 
45
45
  private
46
46
 
47
+ # How many of each measure is necessary to round up to one of the next-largest measure. Note
48
+ # that for simplicity of implementation, we only check one measure when seeing if we should
49
+ # round up. This means that rounding up days to weeks, for instance, cannot draw the line at 3
50
+ # days and 12 hours, but instead either 3 or 4 (whole) days. Let's not even talk about weeks
51
+ # rounding up to months.
52
+ ROUNDING_THRESHOLDS = {
53
+ seconds: 30,
54
+ minutes: 30,
55
+ hours: 12,
56
+ days: 4,
57
+ weeks: 2,
58
+ months: 6,
59
+ years: Float::INFINITY,
60
+ }
61
+
62
+ ROLLUP_THRESHOLDS = {
63
+ seconds: 60,
64
+ minutes: 60,
65
+ hours: 24,
66
+ days: 7,
67
+ weeks: 4, # !!!
68
+ months: 12,
69
+ years: Float::INFINITY,
70
+ }
71
+
47
72
  def normalize_distance_of_time_argument_to_time(value)
48
73
  if value.is_a?(Numeric)
49
74
  Time.at(value)
@@ -63,23 +88,29 @@ module DOTIW
63
88
  end
64
89
 
65
90
  def _display_time_in_words(hash, options = {})
91
+ hash = hash.dup
92
+
66
93
  options = options.reverse_merge(
67
94
  include_seconds: false
68
95
  ).symbolize_keys!
69
96
 
97
+ discarded_hash = {}
98
+
70
99
  include_seconds = options.delete(:include_seconds)
71
- hash.delete(:seconds) if !include_seconds && hash[:minutes]
100
+ discarded_hash[:seconds] = hash.delete(:seconds) if !include_seconds && hash[:minutes]
72
101
 
73
102
  options[:except] = Array.wrap(options[:except]).map!(&:to_sym) if options[:except]
74
103
  options[:only] = Array.wrap(options[:only]).map!(&:to_sym) if options[:only]
75
104
 
76
- # Remove all the values that are nil or excluded. Keep the required ones.
77
- hash.delete_if do |key, value|
78
- value.nil? || value.zero? ||
79
- options[:except]&.include?(key) ||
80
- (options[:only] && !options[:only].include?(key))
105
+ DOTIW::TimeHash::TIME_FRACTIONS.each do |fraction|
106
+ if options[:except]&.include?(fraction) || (options[:only] && !options[:only].include?(fraction))
107
+ discarded_hash[fraction] = hash.delete fraction
108
+ end
81
109
  end
82
110
 
111
+ hash.delete_if { |key, value| value.nil? || value.zero? }
112
+ discarded_hash.delete_if { |key, value| value.nil? || value.zero? }
113
+
83
114
  i18n_scope = options.delete(:scope) || DOTIW::DEFAULT_I18N_SCOPE
84
115
  if hash.empty?
85
116
  fractions = DOTIW::TimeHash::TIME_FRACTIONS
@@ -94,16 +125,22 @@ module DOTIW
94
125
  end
95
126
  end
96
127
 
97
- output = []
98
- I18n.with_options locale: options[:locale], scope: i18n_scope do |locale|
99
- output = hash.map { |key, value| locale.t(key, count: value) }
100
- end
101
-
102
128
  options.delete(:except)
103
129
  options.delete(:only)
104
- highest_measures = options.delete(:highest_measures)
105
- highest_measures = 1 if options.delete(:highest_measure_only)
106
- output = output[0...highest_measures] if highest_measures
130
+
131
+ highest_measures = _compute_highest_measures! options
132
+ if highest_measures
133
+ high_entries, low_entries = hash.to_a.partition.with_index { |_, index| index < highest_measures[:max] }
134
+ hash = high_entries.to_h
135
+ discarded_hash.merge! low_entries.to_h
136
+
137
+ _maybe_round! hash, discarded_hash, highest_measures[:remainder]
138
+ end
139
+
140
+ phrases = []
141
+ I18n.with_options locale: options[:locale], scope: i18n_scope do |locale|
142
+ phrases = hash.map { |key, value| locale.t(key, count: value) }
143
+ end
107
144
 
108
145
  options[:words_connector] ||= I18n.translate :"#{i18n_scope}.words_connector",
109
146
  default: :'support.array.words_connector',
@@ -115,7 +152,56 @@ module DOTIW
115
152
  default: :'support.array.last_word_connector',
116
153
  locale: options[:locale]
117
154
 
118
- output.to_sentence(options.except(:accumulate_on, :compact))
155
+ phrases.to_sentence(options.except(:accumulate_on, :compact))
156
+ end
157
+
158
+ def _compute_highest_measures!(options)
159
+ highest_measures = options.delete(:highest_measures)
160
+ highest_measures = 1 if options.delete(:highest_measure_only)
161
+ highest_measures = { max: highest_measures } if highest_measures.is_a?(Integer)
162
+ highest_measures = highest_measures.reverse_merge(max: 1, remainder: :floor) if highest_measures
163
+
164
+ highest_measures
165
+ end
166
+
167
+ def _maybe_round!(hash, discarded_hash, remainder)
168
+ smallest_measure_index = DOTIW::TimeHash::TIME_FRACTIONS.index hash.to_a.last[0]
169
+ smallest_measure = DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index]
170
+
171
+ case remainder
172
+ when :floor
173
+ # Nothing to do.
174
+ when :ceiling
175
+ # We already filtered out zeroes, so non-empty also means non-zero.
176
+ if !discarded_hash.empty?
177
+ hash[smallest_measure] += 1
178
+ _rollup! hash, smallest_measure_index
179
+ end
180
+ when :round
181
+ # If our smallest measure is already the smallest possible measure, there is no next
182
+ # smallest measure to inspect to see if we need to round up.
183
+ return if smallest_measure_index == 0
184
+
185
+ next_smallest_measure = DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index - 1]
186
+ if discarded_hash.fetch(next_smallest_measure, 0) >= ROUNDING_THRESHOLDS[next_smallest_measure]
187
+ hash[smallest_measure] += 1
188
+ _rollup! hash, smallest_measure_index
189
+ end
190
+ else
191
+ raise ArgumentError, "unrecognized remainder value #{remainder.inspect}"
192
+ end
193
+ end
194
+
195
+ def _rollup!(hash, smallest_measure_index)
196
+ DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index..-1].each_with_index do |fraction, index|
197
+ if hash.fetch(fraction, 0) >= ROLLUP_THRESHOLDS[fraction]
198
+ hash.delete fraction
199
+ next_fraction = DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index + index + 1]
200
+ hash[next_fraction] = hash.fetch(next_fraction, 0) + 1
201
+ else
202
+ break
203
+ end
204
+ end
119
205
  end
120
206
  end
121
207
  end
@@ -43,8 +43,6 @@ module DOTIW
43
43
  def build_time_hash
44
44
  if accumulate_on = options[:accumulate_on]
45
45
  accumulate_on = accumulate_on.to_sym
46
- return build_time_hash if accumulate_on == :years
47
-
48
46
  TIME_FRACTIONS.index(accumulate_on).downto(0) { |i| send("build_#{TIME_FRACTIONS[i]}") }
49
47
  else
50
48
  while distance > 0
@@ -91,11 +89,15 @@ module DOTIW
91
89
  def build_months
92
90
  build_years_months_weeks_days
93
91
 
94
- if (years = output.delete(:years)) > 0
92
+ if options[:accumulate_on]&.to_sym == :months && (years = output.delete(:years)) > 0
95
93
  output[:months] += (years * 12)
96
94
  end
97
95
  end
98
96
 
97
+ def build_years
98
+ build_years_months_weeks_days
99
+ end
100
+
99
101
  def build_years_months_weeks_days
100
102
  months = (largest.year - smallest.year) * 12 + (largest.month - smallest.month)
101
103
  years, months = months.divmod(12)
data/lib/dotiw/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DOTIW
4
- VERSION = '5.3.3'
4
+ VERSION = '5.5.0'
5
5
  end
data/lib/dotiw.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'i18n'
4
-
4
+ require 'logger'
5
5
  require 'active_support'
6
6
  require 'active_support/core_ext'
7
7
 
@@ -13,10 +13,12 @@ describe 'A better distance_of_time_in_words' do
13
13
  include DOTIW::Methods
14
14
  end
15
15
 
16
- START_TIME = '01-08-2009'.to_time
16
+ START_TIME = '01-08-2009'.to_time(:utc)
17
17
 
18
18
  before do
19
19
  I18n.locale = :en
20
+ ActiveSupport.to_time_preserves_timezone = :zone
21
+
20
22
  allow(Time).to receive(:now).and_return(START_TIME)
21
23
  allow(Time.zone).to receive(:now).and_return(START_TIME)
22
24
  end
@@ -113,12 +115,18 @@ describe 'A better distance_of_time_in_words' do
113
115
  context category do
114
116
  fixtures.each_pair do |k, v|
115
117
  it v do
118
+ options = {
119
+ locale: lang
120
+ }
121
+
122
+ options[:compact] = true if category.split.include?('compact')
123
+
116
124
  expect(
117
125
  distance_of_time_in_words(
118
126
  START_TIME,
119
127
  START_TIME + eval(k),
120
128
  true,
121
- locale: lang
129
+ options
122
130
  )
123
131
  ).to eq(v)
124
132
  end
@@ -165,7 +173,7 @@ describe 'A better distance_of_time_in_words' do
165
173
  [Time.zone.now, Time.zone.now + 15.days - 1.minute, '14 days, 23 hours, and 59 minutes'],
166
174
  [Time.zone.now, Time.zone.now + 29.days - 1.minute, '28 days, 23 hours, and 59 minutes'],
167
175
  [Time.zone.now, Time.zone.now + 30.days - 1.minute, '29 days, 23 hours, and 59 minutes'],
168
- [Time.zone.now, Time.zone.now + 31.days - 1.minute, '30 days, 23 hours, and 59 minutes'],
176
+ [Time.zone.now, Time.zone.now + 31.day - 1.minute, '30 days, 23 hours, and 59 minutes'],
169
177
  [Time.zone.now, Time.zone.now + 32.days - 1.minute, '31 days, 23 hours, and 59 minutes'],
170
178
  [Time.zone.now, Time.zone.now + 33.days - 1.minute, '32 days, 23 hours, and 59 minutes']
171
179
  ].each do |start, finish, output|
@@ -211,7 +219,8 @@ describe 'A better distance_of_time_in_words' do
211
219
  START_TIME + 2.day + 10_000.hour + 10.second,
212
220
  :months,
213
221
  '13 months, 3 weeks, 1 day, 16 hours, and 10 seconds'],
214
- ['2015-1-15'.to_time, '2016-3-15'.to_time, :months, '14 months']
222
+ ['2015-1-15'.to_time, '2016-3-15'.to_time, :months, '14 months'],
223
+ ['2015-1-15'.to_time, '2016-3-15'.to_time, :years, '1 year and 2 months']
215
224
  ].each do |start, finish, accumulator, output|
216
225
  it "should be #{output}" do
217
226
  expect(distance_of_time_in_words(start, finish, true, accumulate_on: accumulator)).to eq(output)
@@ -329,7 +338,7 @@ describe 'A better distance_of_time_in_words' do
329
338
  { highest_measures: 3 },
330
339
  '1 year and 2 weeks'],
331
340
  [START_TIME,
332
- START_TIME + 1.days,
341
+ START_TIME + 1.day,
333
342
  { only: %i[years months] },
334
343
  'less than 1 month'],
335
344
  [START_TIME,
@@ -337,15 +346,55 @@ describe 'A better distance_of_time_in_words' do
337
346
  { except: %i[hours minutes seconds] },
338
347
  'less than 1 day'],
339
348
  [START_TIME,
340
- START_TIME + 1.days,
349
+ START_TIME + 1.day,
341
350
  { highest_measures: 1, only: %i[years months] },
342
- 'less than 1 month']
351
+ 'less than 1 month'],
352
+ [START_TIME,
353
+ START_TIME + 1.day + 1.hour,
354
+ { highest_measures: {} },
355
+ '1 day'],
356
+ [START_TIME,
357
+ START_TIME + 1.day + 1.hour,
358
+ { highest_measures: { remainder: :floor} },
359
+ '1 day'],
360
+ [START_TIME,
361
+ START_TIME + 1.year + 1.minute,
362
+ { highest_measures: { remainder: :ceiling } },
363
+ '2 years'],
364
+ [START_TIME,
365
+ START_TIME + 1.day + 2.hours + 30.minutes,
366
+ { highest_measures: { max: 2, remainder: :round } },
367
+ '1 day and 3 hours'],
368
+ [START_TIME,
369
+ START_TIME + 1.day + 23.hours + 59.minutes + 59.seconds,
370
+ { highest_measures: { max: 3, remainder: :round } },
371
+ '2 days'],
372
+ [START_TIME,
373
+ START_TIME + 1.day,
374
+ { highest_measures: { remainder: :ceiling }, only: :months },
375
+ 'less than 1 month'],
376
+ [START_TIME,
377
+ # Simplistic rounding: one would expect this to round up to a second week.
378
+ START_TIME + 1.week + 3.days + 23.hours,
379
+ { highest_measures: { remainder: :round } },
380
+ '1 week'],
381
+ [START_TIME,
382
+ # Simplistic rounding: in some months, 15 days is less than half, but we always round it up.
383
+ START_TIME + 1.month + 14.days,
384
+ { highest_measures: { remainder: :round } },
385
+ '2 months'],
343
386
  ].each do |start, finish, options, output|
344
387
  it "should be #{output}" do
345
388
  expect(distance_of_time_in_words(start, finish, true, options)).to eq(output)
346
389
  end
347
390
  end
348
391
 
392
+ it "raises ArgumentError when an unrecognized value is passed for highest_measure.remainder" do
393
+ expect do
394
+ distance_of_time_in_words(START_TIME, START_TIME + 1.day, true, { highest_measures: { remainder: :oops }})
395
+ end.to raise_error(ArgumentError)
396
+ end
397
+
349
398
  if defined?(ActionView)
350
399
  describe 'ActionView without include seconds argument' do
351
400
  [
@@ -397,7 +446,7 @@ describe 'A better distance_of_time_in_words' do
397
446
  expect(distance_of_time_in_words(start, finish, true, options)).to eq(output)
398
447
  end
399
448
  end
400
-
449
+
401
450
  context 'via ActionController::Base.helpers' do
402
451
  it '#distance_of_time_in_words' do
403
452
  end_time = START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds
@@ -0,0 +1,21 @@
1
+ seconds:
2
+ 1.second: སྐར་ཆ་ ༡
3
+ 3.seconds: སྐར་ཆ་ 3
4
+ minutes:
5
+ 1.minute: སྐར་མ་ ༡
6
+ 20.minutes: སྐར་མ་ 20
7
+ hours:
8
+ 1.hour: ཆུ་ཚོད་ ༡
9
+ 5.hours: ཆུ་ཚོད་ 5
10
+ days:
11
+ 1.day: ཉིནམ་ ༡
12
+ 6.days: ཉིནམ་ 6
13
+ weeks:
14
+ 1.week: བདུན༌ཕྲག་ ༡
15
+ 2.weeks: བདུན༌ཕྲག་ 2
16
+ months:
17
+ 1.month: ཟླཝ་ ༡
18
+ 9.months: ཟླཝ་ 9
19
+ years:
20
+ 1.year: ལོ་ ༡
21
+ 3.years: ལོ་ 3
data/spec/lib/i18n/ru.yml CHANGED
@@ -3,3 +3,21 @@ seconds:
3
3
  1.second: 1 секунда
4
4
  minutes:
5
5
  1.minute: 1 минута
6
+ compact seconds:
7
+ 1.second: 1с
8
+ 11.seconds: 11с
9
+ 21.seconds: 21с
10
+ compact minutes:
11
+ 1.minute: 1м
12
+ 11.minutes: 11м
13
+ 21.minutes: 21м
14
+ compact hours:
15
+ 1.hour: 1ч
16
+ 11.hours: 11ч
17
+ 21.hours: 21ч
18
+ compact days:
19
+ 1.day: 1д
20
+ compact years:
21
+ 1.year: 1г
22
+ 11.years: 11г
23
+ 21.years: 21г
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotiw
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.3.3
4
+ version: 5.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Bigg
8
8
  - Lauran Jansen
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2022-04-25 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
@@ -123,6 +122,48 @@ dependencies:
123
122
  - - "~>"
124
123
  - !ruby/object:Gem::Version
125
124
  version: 1.2.7
125
+ - !ruby/object:Gem::Dependency
126
+ name: mutex_m
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: base64
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: bigdecimal
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
126
167
  description: |-
127
168
  dotiw is a gem for Rails that overrides the
128
169
  default distance_of_time_in_words and provides
@@ -141,6 +182,7 @@ files:
141
182
  - ".rspec"
142
183
  - Appraisals
143
184
  - CHANGELOG.md
185
+ - CODEOWNERS
144
186
  - CONTRIBUTING.md
145
187
  - Gemfile
146
188
  - MIT-LICENSE
@@ -149,16 +191,19 @@ files:
149
191
  - benchmarks/time_hash_bench.rb
150
192
  - dotiw.gemspec
151
193
  - gemfiles/.bundle/config
152
- - gemfiles/rails_4.gemfile
153
194
  - gemfiles/rails_5.0.gemfile
154
195
  - gemfiles/rails_5.1.gemfile
155
196
  - gemfiles/rails_5.2.gemfile
156
197
  - gemfiles/rails_6.0.gemfile
198
+ - gemfiles/rails_7.0.gemfile
199
+ - gemfiles/rails_7.1.gemfile
200
+ - gemfiles/rails_7.2.gemfile
157
201
  - lib/dotiw.rb
158
202
  - lib/dotiw/action_view/helpers/date_helper.rb
159
203
  - lib/dotiw/locale/ar.yml
160
204
  - lib/dotiw/locale/da.yml
161
205
  - lib/dotiw/locale/de.yml
206
+ - lib/dotiw/locale/dz.yml
162
207
  - lib/dotiw/locale/en.yml
163
208
  - lib/dotiw/locale/es.yml
164
209
  - lib/dotiw/locale/fr.yml
@@ -182,6 +227,7 @@ files:
182
227
  - spec/lib/i18n/ar.yml
183
228
  - spec/lib/i18n/da.yml
184
229
  - spec/lib/i18n/de.yml
230
+ - spec/lib/i18n/dz.yml
185
231
  - spec/lib/i18n/en.yml
186
232
  - spec/lib/i18n/es.yml
187
233
  - spec/lib/i18n/fr.yml
@@ -203,7 +249,6 @@ homepage: https://github.com/radar/distance_of_time_in_words
203
249
  licenses:
204
250
  - MIT
205
251
  metadata: {}
206
- post_install_message:
207
252
  rdoc_options: []
208
253
  require_paths:
209
254
  - lib
@@ -218,8 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
263
  - !ruby/object:Gem::Version
219
264
  version: '0'
220
265
  requirements: []
221
- rubygems_version: 3.1.3
222
- signing_key:
266
+ rubygems_version: 3.6.9
223
267
  specification_version: 4
224
268
  summary: Better distance_of_time_in_words for Rails
225
269
  test_files:
@@ -227,6 +271,7 @@ test_files:
227
271
  - spec/lib/i18n/ar.yml
228
272
  - spec/lib/i18n/da.yml
229
273
  - spec/lib/i18n/de.yml
274
+ - spec/lib/i18n/dz.yml
230
275
  - spec/lib/i18n/en.yml
231
276
  - spec/lib/i18n/es.yml
232
277
  - spec/lib/i18n/fr.yml