dotiw 4.0.1 → 5.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|