dotiw 4.0.1 → 5.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +45 -0
- data/.rspec +2 -0
- data/Appraisals +19 -0
- data/CHANGELOG.md +42 -6
- data/Gemfile +2 -0
- data/MIT-LICENSE +1 -1
- data/README.markdown +151 -63
- data/Rakefile +3 -1
- data/benchmarks/time_hash_bench.rb +19 -0
- data/dotiw.gemspec +17 -19
- data/gemfiles/rails_4.gemfile +5 -3
- data/gemfiles/rails_5.0.gemfile +5 -3
- data/gemfiles/rails_5.1.gemfile +5 -3
- data/gemfiles/rails_5.2.gemfile +9 -0
- data/gemfiles/rails_6.0.gemfile +9 -0
- data/lib/dotiw.rb +33 -14
- data/lib/dotiw/action_view/helpers/date_helper.rb +32 -0
- data/lib/dotiw/locale/ar.yml +84 -26
- data/lib/dotiw/locale/da.yml +35 -0
- data/lib/dotiw/locale/de.yml +36 -1
- data/lib/dotiw/locale/en.yml +35 -0
- data/lib/dotiw/locale/es.yml +36 -1
- data/lib/dotiw/locale/fr.yml +35 -0
- data/lib/dotiw/locale/id.yml +35 -0
- data/lib/dotiw/locale/it.yml +35 -0
- data/lib/dotiw/locale/ja.yml +35 -0
- data/lib/dotiw/locale/ko.yml +23 -0
- data/lib/dotiw/locale/nb.yml +36 -1
- data/lib/dotiw/locale/nl.yml +35 -0
- data/lib/dotiw/locale/pl.yml +42 -0
- data/lib/dotiw/locale/pt-BR.yml +35 -0
- data/lib/dotiw/locale/ru.yml +37 -0
- data/lib/dotiw/locale/sv.yml +48 -0
- data/lib/dotiw/locale/vi.yml +48 -0
- data/lib/dotiw/locale/zh-CN.yml +23 -0
- data/lib/dotiw/locale/zh-TW.yml +60 -0
- data/lib/dotiw/methods.rb +108 -0
- data/lib/dotiw/time_hash.rb +52 -40
- data/lib/dotiw/version.rb +2 -2
- data/spec/lib/dotiw_spec.rb +304 -159
- data/spec/lib/i18n/ar.yml +2 -0
- data/spec/lib/i18n/da.yml +2 -0
- data/spec/lib/i18n/de.yml +2 -0
- data/spec/lib/i18n/en.yml +2 -0
- data/spec/lib/i18n/es.yml +3 -0
- data/spec/lib/i18n/fr.yml +2 -0
- data/spec/lib/i18n/id.yml +2 -0
- data/spec/lib/i18n/it.yml +3 -0
- data/spec/lib/i18n/ja.yml +2 -0
- data/spec/lib/i18n/ko.yml +2 -0
- data/spec/lib/i18n/nb.yml +2 -0
- data/spec/lib/i18n/nl.yml +2 -0
- data/spec/lib/i18n/pl.yml +2 -0
- data/spec/lib/i18n/pt-BR.yml +2 -0
- data/spec/lib/i18n/ru.yml +5 -0
- data/spec/lib/i18n/sv.yml +2 -0
- data/spec/lib/i18n/vi.yml +22 -0
- data/spec/lib/i18n/zh-CN.yml +2 -0
- data/spec/lib/i18n/zh-TW.yml +2 -0
- data/spec/spec_helper.rb +2 -9
- metadata +76 -30
- data/.travis.yml +0 -27
- data/lib/dotiw/action_view_ext/helpers/date_helper.rb +0 -103
data/lib/dotiw/version.rb
CHANGED
data/spec/lib/dotiw_spec.rb
CHANGED
@@ -1,13 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
describe 'A better distance_of_time_in_words' do
|
6
|
+
if defined?(ActionView)
|
7
|
+
include ActionView::Helpers::DateHelper
|
8
|
+
include ActionView::Helpers::TextHelper
|
9
|
+
include ActionView::Helpers::NumberHelper
|
9
10
|
|
10
|
-
|
11
|
+
require 'action_controller'
|
12
|
+
else
|
13
|
+
include DOTIW::Methods
|
14
|
+
end
|
15
|
+
|
16
|
+
START_TIME = '01-08-2009'.to_time
|
11
17
|
|
12
18
|
before do
|
13
19
|
I18n.locale = :en
|
@@ -15,57 +21,57 @@ describe "A better distance_of_time_in_words" do
|
|
15
21
|
allow(Time.zone).to receive(:now).and_return(START_TIME)
|
16
22
|
end
|
17
23
|
|
18
|
-
describe
|
19
|
-
|
20
|
-
[0.5.minutes,
|
21
|
-
[4.5.minutes,
|
22
|
-
[5.minutes.to_i,
|
23
|
-
[10.minutes.to_i,
|
24
|
-
[1.hour.to_i,
|
25
|
-
[1.hour + 30.seconds,
|
26
|
-
[4.weeks.to_i,
|
27
|
-
[4.weeks + 2.days,
|
28
|
-
[24.weeks.to_i,
|
29
|
-
]
|
30
|
-
fragments.each do |number, result|
|
24
|
+
describe '#distance_of_time' do
|
25
|
+
[
|
26
|
+
[0.5.minutes, '30 seconds', '30s'],
|
27
|
+
[4.5.minutes, '4 minutes and 30 seconds', '4m30s'],
|
28
|
+
[5.minutes.to_i, '5 minutes', '5m'],
|
29
|
+
[10.minutes.to_i, '10 minutes', '10m'],
|
30
|
+
[1.hour.to_i, '1 hour', '1h'],
|
31
|
+
[1.hour + 30.seconds, '1 hour and 30 seconds', '1h30s'],
|
32
|
+
[4.weeks.to_i, '4 weeks', '4w'],
|
33
|
+
[4.weeks + 2.days, '4 weeks and 2 days', '4w2d'],
|
34
|
+
[24.weeks.to_i, '5 months, 2 weeks, and 1 day', '5mo2w1d']
|
35
|
+
].each do |number, result, compact_result|
|
31
36
|
it "#{number} == #{result}" do
|
32
37
|
expect(distance_of_time(number)).to eq(result)
|
38
|
+
expect(distance_of_time(number, compact: true)).to eq(compact_result)
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
|
-
describe
|
37
|
-
it
|
38
|
-
expect(distance_of_time(1.2.minute, except: 'seconds')).to eq(
|
39
|
-
expect(distance_of_time(2.5.hours + 30.seconds, except: 'seconds')).to eq(
|
42
|
+
describe 'with options' do
|
43
|
+
it 'except:seconds should skip seconds' do
|
44
|
+
expect(distance_of_time(1.2.minute, except: 'seconds')).to eq('1 minute')
|
45
|
+
expect(distance_of_time(2.5.hours + 30.seconds, except: 'seconds')).to eq('2 hours and 30 minutes')
|
40
46
|
end
|
41
47
|
|
42
|
-
it
|
48
|
+
it 'except:seconds has higher precedence than include_seconds:true' do
|
43
49
|
expect(distance_of_time(1.2.minute, include_seconds: true, except: 'seconds')).to eq('1 minute')
|
44
50
|
end
|
45
51
|
end
|
46
|
-
|
47
52
|
end
|
48
53
|
|
49
|
-
describe
|
50
|
-
describe
|
51
|
-
|
52
|
-
[:years, :months, :weeks, :days, :minutes, :seconds].each do |name|
|
54
|
+
describe '#distance_of_time_in_words_hash' do
|
55
|
+
describe 'giving correct numbers of' do
|
56
|
+
%i[years months weeks days minutes seconds].each do |name|
|
53
57
|
describe name do
|
54
|
-
it
|
58
|
+
it 'exactly' do
|
55
59
|
hash = distance_of_time_in_words_hash(START_TIME, START_TIME + 1.send(name))
|
56
60
|
expect(hash[name]).to eq(1)
|
57
61
|
end
|
58
62
|
|
59
|
-
it
|
63
|
+
it 'two' do
|
60
64
|
hash = distance_of_time_in_words_hash(START_TIME, START_TIME + 2.send(name))
|
61
65
|
expect(hash[name]).to eq(2)
|
62
66
|
end
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
66
|
-
it
|
67
|
-
hash = distance_of_time_in_words_hash(
|
68
|
-
|
70
|
+
it 'should be happy with lots of measurements' do
|
71
|
+
hash = distance_of_time_in_words_hash(
|
72
|
+
START_TIME,
|
73
|
+
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds
|
74
|
+
)
|
69
75
|
expect(hash[:years]).to eq(1)
|
70
76
|
expect(hash[:months]).to eq(2)
|
71
77
|
expect(hash[:weeks]).to eq(3)
|
@@ -77,214 +83,353 @@ describe "A better distance_of_time_in_words" do
|
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
80
|
-
describe
|
81
|
-
it
|
82
|
-
expect(
|
83
|
-
expect(distance_of_time_in_words(START_TIME, START_TIME + 5.days, :locale => :es)).to eq("5 días")
|
86
|
+
describe '#time_ago_in_words' do
|
87
|
+
it 'aliases to distance_of_time_in_words' do
|
88
|
+
expect(time_ago_in_words(Time.now - 3.days - 14.minutes)).to eq('3 days and 14 minutes')
|
84
89
|
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#distance_of_time_in_words' do
|
93
|
+
context 'locale' do
|
94
|
+
it 'includes known languages' do
|
95
|
+
expect(DOTIW.languages).to include :en
|
96
|
+
expect(DOTIW.languages).to include :ru
|
97
|
+
end
|
85
98
|
|
86
|
-
|
87
|
-
|
88
|
-
|
99
|
+
it 'includes all the languages in specs' do
|
100
|
+
languages = Dir[File.join(File.dirname(__FILE__), 'i18n', '*.yml')].map { |f| File.basename(f, '.yml') }
|
101
|
+
expect(DOTIW.languages.map(&:to_s).sort).to eq languages.sort
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'raises ArgumentError when nil is passed for time' do
|
105
|
+
expect { distance_of_time_in_words(nil) }.to raise_error(ArgumentError)
|
106
|
+
expect { distance_of_time_in_words(nil, nil) }.to raise_error(ArgumentError)
|
107
|
+
end
|
108
|
+
|
109
|
+
DOTIW.languages.each do |lang|
|
110
|
+
context lang do
|
111
|
+
YAML.safe_load(
|
112
|
+
File.read(
|
113
|
+
File.join(
|
114
|
+
File.dirname(__FILE__), 'i18n', "#{lang}.yml"
|
115
|
+
)
|
116
|
+
)
|
117
|
+
).each_pair do |category, fixtures|
|
118
|
+
context category do
|
119
|
+
fixtures.each_pair do |k, v|
|
120
|
+
it v do
|
121
|
+
expect(
|
122
|
+
distance_of_time_in_words(
|
123
|
+
START_TIME,
|
124
|
+
START_TIME + eval(k),
|
125
|
+
true,
|
126
|
+
locale: lang
|
127
|
+
)
|
128
|
+
).to eq(v)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
89
135
|
end
|
90
136
|
|
91
|
-
|
92
|
-
[START_TIME, START_TIME + 5.days + 3.minutes,
|
93
|
-
[START_TIME, START_TIME + 1.minute,
|
94
|
-
[START_TIME, START_TIME + 3.years,
|
95
|
-
[START_TIME, START_TIME + 10.years,
|
96
|
-
[START_TIME, START_TIME + 8.months,
|
97
|
-
[START_TIME, START_TIME + 3.hour,
|
98
|
-
[START_TIME, START_TIME + 13.months,
|
137
|
+
[
|
138
|
+
[START_TIME, START_TIME + 5.days + 3.minutes, '5 days and 3 minutes', '5d3m'],
|
139
|
+
[START_TIME, START_TIME + 1.minute, '1 minute', '1m'],
|
140
|
+
[START_TIME, START_TIME + 3.years, '3 years', '3y'],
|
141
|
+
[START_TIME, START_TIME + 10.years, '10 years', '10y'],
|
142
|
+
[START_TIME, START_TIME + 8.months, '8 months', '8mo'],
|
143
|
+
[START_TIME, START_TIME + 3.hour, '3 hours', '3h'],
|
144
|
+
[START_TIME, START_TIME + 13.months, '1 year and 1 month', '1y1mo'],
|
99
145
|
# Any numeric sequence is merely coincidental.
|
100
|
-
[START_TIME, START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
101
|
-
|
102
|
-
[
|
103
|
-
[
|
104
|
-
[
|
105
|
-
[
|
106
|
-
|
107
|
-
|
146
|
+
[START_TIME, START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
147
|
+
'1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, and 7 seconds', '1y2mo3w4d5h6m7s'],
|
148
|
+
['2009-3-16'.to_time, '2008-4-14'.to_time, '11 months and 2 days', '11mo2d'],
|
149
|
+
['2009-3-16'.to_time + 1.minute, '2008-4-14'.to_time, '11 months, 2 days, and 1 minute', '11mo2d1m'],
|
150
|
+
['2009-4-14'.to_time, '2008-3-16'.to_time, '1 year, 4 weeks, and 1 day', '1y4w1d'],
|
151
|
+
['2009-2-01'.to_time, '2009-3-01'.to_time, '1 month', '1mo'],
|
152
|
+
['2008-2-01'.to_time, '2008-3-01'.to_time, '1 month', '1mo'],
|
153
|
+
[Date.parse('31.03.2015').to_time, Time.parse('01.03.2016'), '10 months, 4 weeks, and 2 days', '10mo4w2d'],
|
154
|
+
[Date.new(2014, 1, 31), Date.new(2014, 3, 1), '4 weeks and 1 day', '4w1d'],
|
155
|
+
['2008-2-01'.to_time, '2008-3-01'.to_time, '1 month', '1mo'],
|
156
|
+
['2014-1-31'.to_time, '2014-3-01'.to_time, '4 weeks and 1 day', '4w1d'],
|
157
|
+
['2014-1-31'.to_time, '2014-3-02'.to_time, '4 weeks and 2 days', '4w2d'],
|
158
|
+
['2016-1-31'.to_time, '2016-3-01'.to_time, '4 weeks and 2 days', '4w2d'],
|
159
|
+
['2016-1-31'.to_time, '2016-3-02'.to_time, '1 month', '1mo']
|
160
|
+
].each do |start, finish, output, compact_result|
|
108
161
|
it "should be #{output}" do
|
109
162
|
expect(distance_of_time_in_words(start, finish, true)).to eq(output)
|
163
|
+
expect(distance_of_time_in_words(finish, start, true)).to eq(output)
|
164
|
+
expect(distance_of_time_in_words(start, finish, true, compact: true)).to eq(compact_result)
|
110
165
|
end
|
111
166
|
end
|
112
167
|
|
113
|
-
|
114
|
-
|
168
|
+
[
|
169
|
+
[Time.zone.now, Time.zone.now + 1.day - 1.minute, '23 hours and 59 minutes'],
|
170
|
+
[Time.zone.now, Time.zone.now + 15.days - 1.minute, '14 days, 23 hours, and 59 minutes'],
|
171
|
+
[Time.zone.now, Time.zone.now + 29.days - 1.minute, '28 days, 23 hours, and 59 minutes'],
|
172
|
+
[Time.zone.now, Time.zone.now + 30.days - 1.minute, '29 days, 23 hours, and 59 minutes'],
|
173
|
+
[Time.zone.now, Time.zone.now + 31.days - 1.minute, '30 days, 23 hours, and 59 minutes'],
|
174
|
+
[Time.zone.now, Time.zone.now + 32.days - 1.minute, '31 days, 23 hours, and 59 minutes'],
|
175
|
+
[Time.zone.now, Time.zone.now + 33.days - 1.minute, '32 days, 23 hours, and 59 minutes']
|
176
|
+
].each do |start, finish, output|
|
177
|
+
it "should be #{output}" do
|
178
|
+
expect(distance_of_time_in_words(start, finish, accumulate_on: 'days')).to eq(output)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
[
|
183
|
+
[Time.at(1), Time.at(100), '1 minute'],
|
184
|
+
[DateTime.now, DateTime.now + 1.minute, '1 minute'],
|
185
|
+
[Date.new(2000, 1, 2), Date.new(2000, 1, 3), '1 day'],
|
186
|
+
[Time.at(DateTime.now), DateTime.now + 1.minute, '1 minute']
|
187
|
+
].each do |start, finish, output|
|
188
|
+
it "should be #{output}" do
|
189
|
+
expect(distance_of_time_in_words(start, finish)).to eq(output)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe 'accumulate_on:' do
|
194
|
+
[
|
115
195
|
[START_TIME,
|
116
196
|
START_TIME + 10.minute,
|
117
197
|
:seconds,
|
118
|
-
|
198
|
+
'600 seconds'],
|
119
199
|
[START_TIME,
|
120
200
|
START_TIME + 10.hour + 10.minute + 1.second,
|
121
201
|
:minutes,
|
122
|
-
|
202
|
+
'610 minutes and 1 second'],
|
123
203
|
[START_TIME,
|
124
|
-
START_TIME + 2.day +
|
204
|
+
START_TIME + 2.day + 10_000.hour + 10.second,
|
125
205
|
:hours,
|
126
|
-
|
206
|
+
'10048 hours and 10 seconds'],
|
127
207
|
[START_TIME,
|
128
|
-
START_TIME + 2.day +
|
208
|
+
START_TIME + 2.day + 10_000.hour + 10.second,
|
129
209
|
:days,
|
130
|
-
|
210
|
+
'418 days, 16 hours, and 10 seconds'],
|
131
211
|
[START_TIME,
|
132
|
-
START_TIME + 2.day +
|
212
|
+
START_TIME + 2.day + 10_000.hour + 10.second,
|
133
213
|
:weeks,
|
134
|
-
|
214
|
+
'59 weeks, 5 days, 16 hours, and 10 seconds'],
|
135
215
|
[START_TIME,
|
136
|
-
START_TIME + 2.day +
|
216
|
+
START_TIME + 2.day + 10_000.hour + 10.second,
|
137
217
|
:months,
|
138
|
-
|
139
|
-
[
|
140
|
-
|
141
|
-
]
|
142
|
-
fragments.each do |start, finish, accumulator, output|
|
218
|
+
'13 months, 3 weeks, 1 day, 16 hours, and 10 seconds'],
|
219
|
+
['2015-1-15'.to_time, '2016-3-15'.to_time, :months, '14 months']
|
220
|
+
].each do |start, finish, accumulator, output|
|
143
221
|
it "should be #{output}" do
|
144
|
-
expect(distance_of_time_in_words(start, finish, true, :
|
222
|
+
expect(distance_of_time_in_words(start, finish, true, accumulate_on: accumulator)).to eq(output)
|
145
223
|
end
|
146
224
|
end
|
147
|
-
end
|
225
|
+
end
|
148
226
|
|
149
|
-
describe
|
227
|
+
describe 'without finish time' do
|
150
228
|
# A missing finish argument should default to zero, essentially returning
|
151
229
|
# the equivalent of distance_of_time in order to be backwards-compatible
|
152
230
|
# with the original rails distance_of_time_in_words helper.
|
153
|
-
|
154
|
-
[5.minutes.to_i,
|
155
|
-
[10.minutes.to_i,
|
156
|
-
[1.hour.to_i,
|
157
|
-
[6.days.to_i,
|
158
|
-
[4.weeks.to_i,
|
159
|
-
[24.weeks.to_i,
|
160
|
-
]
|
161
|
-
fragments.each do |start, output|
|
231
|
+
[
|
232
|
+
[5.minutes.to_i, '5 minutes'],
|
233
|
+
[10.minutes.to_i, '10 minutes'],
|
234
|
+
[1.hour.to_i, '1 hour'],
|
235
|
+
[6.days.to_i, '6 days'],
|
236
|
+
[4.weeks.to_i, '4 weeks'],
|
237
|
+
[24.weeks.to_i, '5 months, 2 weeks, and 1 day']
|
238
|
+
].each do |start, output|
|
162
239
|
it "should be #{output}" do
|
163
240
|
expect(distance_of_time_in_words(start)).to eq(output)
|
164
241
|
end
|
165
242
|
end
|
166
243
|
end
|
167
|
-
|
168
244
|
end
|
169
245
|
|
170
|
-
describe
|
171
|
-
|
246
|
+
describe 'with output options' do
|
247
|
+
[
|
172
248
|
# Any numeric sequence is merely coincidental.
|
173
249
|
[START_TIME,
|
174
250
|
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
175
|
-
{ :
|
176
|
-
|
251
|
+
{ words_connector: ' - ' },
|
252
|
+
'1 year - 2 months - 3 weeks - 4 days - 5 hours - 6 minutes, and 7 seconds'],
|
177
253
|
[START_TIME,
|
178
254
|
START_TIME + 5.minutes + 6.seconds,
|
179
|
-
{ :
|
180
|
-
|
255
|
+
{ two_words_connector: ' - ' },
|
256
|
+
'5 minutes - 6 seconds'],
|
181
257
|
[START_TIME,
|
182
|
-
START_TIME + 4.hours +
|
183
|
-
{ :
|
184
|
-
|
258
|
+
START_TIME + 4.hours + 5.minutes + 6.seconds,
|
259
|
+
{ last_word_connector: ' - ' },
|
260
|
+
'4 hours, 5 minutes - 6 seconds'],
|
185
261
|
[START_TIME,
|
186
262
|
START_TIME + 1.year + 2.months + 3.days + 4.hours + 5.minutes + 6.seconds,
|
187
|
-
{ :
|
188
|
-
|
263
|
+
{ except: 'minutes' },
|
264
|
+
'1 year, 2 months, 3 days, 4 hours, and 6 seconds'],
|
189
265
|
[START_TIME,
|
190
266
|
START_TIME + 1.hour + 1.minute,
|
191
|
-
{ :
|
267
|
+
{ except: 'minutes' }, '1 hour'],
|
192
268
|
[START_TIME,
|
193
269
|
START_TIME + 1.hour + 1.day + 1.minute,
|
194
|
-
{ :
|
195
|
-
|
270
|
+
{ except: %w[minutes hours] },
|
271
|
+
'1 day'],
|
196
272
|
[START_TIME,
|
197
273
|
START_TIME + 1.hour + 1.day + 1.minute,
|
198
|
-
{ :
|
199
|
-
|
274
|
+
{ only: %w[minutes hours] },
|
275
|
+
'1 hour and 1 minute'],
|
200
276
|
[START_TIME,
|
201
277
|
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
202
|
-
{ :
|
203
|
-
|
278
|
+
{ except: 'minutes' },
|
279
|
+
'1 year, 2 months, 3 weeks, 4 days, 5 hours, and 7 seconds'],
|
204
280
|
[START_TIME,
|
205
|
-
START_TIME + 1.
|
206
|
-
{ :
|
207
|
-
|
208
|
-
[START_TIME,
|
209
|
-
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
210
|
-
{ :vague => false },
|
211
|
-
"1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, and 7 seconds"],
|
212
|
-
[START_TIME,
|
213
|
-
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
214
|
-
{ :vague => nil },
|
215
|
-
"1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, and 7 seconds"],
|
216
|
-
[START_TIME,
|
217
|
-
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
218
|
-
{ :except => "minutes" },
|
219
|
-
"1 year, 2 months, 3 weeks, 4 days, 5 hours, and 7 seconds"],
|
220
|
-
[START_TIME,
|
221
|
-
START_TIME + 1.hour + 2.minutes + 3.seconds,
|
222
|
-
{ :highest_measure_only => true },
|
223
|
-
"1 hour"],
|
281
|
+
START_TIME + 1.hour + 2.minutes + 3.seconds,
|
282
|
+
{ highest_measure_only: true },
|
283
|
+
'1 hour'],
|
224
284
|
[START_TIME,
|
225
285
|
START_TIME + 1.hours + 2.minutes + 3.seconds,
|
226
|
-
{ :
|
227
|
-
|
286
|
+
{ highest_measures: 1 },
|
287
|
+
'1 hour'],
|
228
288
|
[START_TIME,
|
229
289
|
START_TIME + 2.year + 3.months + 4.days + 5.hours + 6.minutes + 7.seconds,
|
230
|
-
{ :
|
231
|
-
|
290
|
+
{ highest_measures: 3 },
|
291
|
+
'2 years, 3 months, and 4 days'],
|
232
292
|
[START_TIME,
|
233
293
|
START_TIME + 2.year + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
234
|
-
{ :
|
235
|
-
|
294
|
+
{ highest_measures: 2 },
|
295
|
+
'2 years and 3 weeks'],
|
236
296
|
[START_TIME,
|
237
297
|
START_TIME + 4.days + 6.minutes + 7.seconds,
|
238
|
-
{ :
|
239
|
-
|
298
|
+
{ highest_measures: 3 },
|
299
|
+
'4 days, 6 minutes, and 7 seconds'],
|
240
300
|
[START_TIME,
|
241
301
|
START_TIME + 1.year + 2.weeks,
|
242
|
-
{ :
|
243
|
-
|
302
|
+
{ highest_measures: 3 },
|
303
|
+
'1 year and 2 weeks'],
|
244
304
|
[START_TIME,
|
245
305
|
START_TIME + 1.days,
|
246
|
-
{ :
|
247
|
-
|
306
|
+
{ only: %i[years months] },
|
307
|
+
'less than 1 month'],
|
248
308
|
[START_TIME,
|
249
309
|
START_TIME + 5.minutes,
|
250
|
-
{ :
|
251
|
-
|
310
|
+
{ except: %i[hours minutes seconds] },
|
311
|
+
'less than 1 day'],
|
252
312
|
[START_TIME,
|
253
313
|
START_TIME + 1.days,
|
254
|
-
{ :
|
255
|
-
|
256
|
-
]
|
257
|
-
fragments.each do |start, finish, options, output|
|
314
|
+
{ highest_measures: 1, only: %i[years months] },
|
315
|
+
'less than 1 month']
|
316
|
+
].each do |start, finish, options, output|
|
258
317
|
it "should be #{output}" do
|
259
318
|
expect(distance_of_time_in_words(start, finish, true, options)).to eq(output)
|
260
319
|
end
|
261
320
|
end
|
262
321
|
|
263
|
-
|
264
|
-
|
265
|
-
|
322
|
+
if defined?(ActionView)
|
323
|
+
describe 'ActionView' do
|
324
|
+
[
|
325
|
+
[START_TIME,
|
326
|
+
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
327
|
+
{ vague: true },
|
328
|
+
'about 1 year'],
|
329
|
+
[START_TIME,
|
330
|
+
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
331
|
+
{ vague: 'Yes please' },
|
332
|
+
'about 1 year'],
|
333
|
+
[START_TIME,
|
334
|
+
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
335
|
+
{ vague: false },
|
336
|
+
'1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, and 7 seconds'],
|
337
|
+
[START_TIME,
|
338
|
+
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
339
|
+
{ vague: nil },
|
340
|
+
'1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, and 7 seconds']
|
341
|
+
].each do |start, finish, options, output|
|
342
|
+
it "should be #{output}" do
|
343
|
+
expect(distance_of_time_in_words(start, finish, true, options)).to eq(output)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
context 'via ActionController::Base.helpers' do
|
348
|
+
it '#distance_of_time_in_words' do
|
349
|
+
end_time = START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds
|
350
|
+
expected = '1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, and 7 seconds'
|
351
|
+
actual = ActionController::Base.helpers.distance_of_time_in_words(START_TIME, end_time, true,
|
352
|
+
{ vague: false })
|
353
|
+
expect(actual).to eq(expected)
|
354
|
+
end
|
355
|
+
|
356
|
+
it '#time_ago_in_words' do
|
357
|
+
expected = '3 days and 14 minutes'
|
358
|
+
actual = ActionController::Base.helpers.time_ago_in_words(Time.now - 3.days - 14.minutes)
|
359
|
+
expect(actual).to eq(expected)
|
360
|
+
end
|
361
|
+
|
362
|
+
describe '#distance_of_time_in_words_to_now' do
|
363
|
+
context 'with nil' do
|
364
|
+
it 'raises ArgumentError when nil is passed for time' do
|
365
|
+
expect do
|
366
|
+
ActionController::Base.helpers.distance_of_time_in_words_to_now(nil)
|
367
|
+
end.to raise_error(ArgumentError)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context 'without options' do
|
372
|
+
it 'shows detailed duration' do
|
373
|
+
expected = '3 days and 14 minutes'
|
374
|
+
actual = ActionController::Base.helpers.distance_of_time_in_words_to_now(Time.now - 3.days - 14.minutes)
|
375
|
+
expect(actual).to eq(expected)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context 'with vague option true' do
|
380
|
+
it 'shows vague duration' do
|
381
|
+
expected = '3 days'
|
382
|
+
actual = ActionController::Base.helpers.distance_of_time_in_words_to_now(
|
383
|
+
Time.now - 3.days - 14.minutes, false, vague: true
|
384
|
+
)
|
385
|
+
expect(actual).to eq(expected)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
context 'with vague option false' do
|
390
|
+
it 'shows detailed duration' do
|
391
|
+
expected = '3 days and 14 minutes'
|
392
|
+
actual = ActionController::Base.helpers.distance_of_time_in_words_to_now(
|
393
|
+
Time.now - 3.days - 14.minutes, false, vague: false
|
394
|
+
)
|
395
|
+
expect(actual).to eq(expected)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
266
400
|
end
|
401
|
+
end
|
267
402
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
false)).to eq("1 year, 2 months, 3 weeks, 4 days, 5 hours, and 6 minutes")
|
403
|
+
describe 'include_seconds' do
|
404
|
+
it 'is ignored if only seconds have passed' do
|
405
|
+
expect(distance_of_time_in_words(START_TIME, START_TIME + 1.second, false)).to eq('1 second')
|
272
406
|
end
|
273
|
-
end # include_seconds
|
274
|
-
end
|
275
407
|
|
276
|
-
|
277
|
-
|
278
|
-
|
408
|
+
it 'removes seconds in all other cases' do
|
409
|
+
expect(
|
410
|
+
distance_of_time_in_words(
|
411
|
+
START_TIME,
|
412
|
+
START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds,
|
413
|
+
false
|
414
|
+
)
|
415
|
+
).to eq('1 year, 2 months, 3 weeks, 4 days, 5 hours, and 6 minutes')
|
416
|
+
end
|
279
417
|
end
|
418
|
+
end
|
280
419
|
|
281
|
-
|
282
|
-
|
283
|
-
|
420
|
+
if defined?(ActionView)
|
421
|
+
describe 'percentage of time' do
|
422
|
+
def time_in_percent(options = {})
|
423
|
+
distance_of_time_in_percent('04-12-2009'.to_time, '29-01-2010'.to_time, '04-12-2010'.to_time, options)
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'calculates 15%' do
|
427
|
+
expect(time_in_percent).to eq('15%')
|
428
|
+
end
|
284
429
|
|
285
|
-
|
286
|
-
|
430
|
+
it 'calculates 15.3%' do
|
431
|
+
expect(time_in_percent(precision: 1)).to eq('15.3%')
|
432
|
+
end
|
287
433
|
end
|
288
434
|
end
|
289
|
-
|
290
435
|
end
|