groupdate 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -7
- data/CHANGELOG.md +8 -0
- data/README.md +5 -4
- data/Rakefile +1 -1
- data/lib/groupdate.rb +4 -2
- data/lib/groupdate/active_record.rb +10 -8
- data/lib/groupdate/enumerable.rb +6 -4
- data/lib/groupdate/magic.rb +19 -19
- data/lib/groupdate/scopes.rb +6 -6
- data/lib/groupdate/version.rb +1 -1
- data/{gemfiles → test/gemfiles}/activerecord31.gemfile +1 -1
- data/{gemfiles → test/gemfiles}/activerecord32.gemfile +1 -1
- data/{gemfiles → test/gemfiles}/activerecord40.gemfile +1 -1
- data/{gemfiles → test/gemfiles}/activerecord41.gemfile +1 -1
- data/test/gemfiles/activerecord50.gemfile +6 -0
- data/test/mysql_test.rb +1 -1
- data/test/postgresql_test.rb +5 -1
- data/test/test_helper.rb +124 -50
- metadata +13 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e50a64260e2d0aa3ce8675cce56a1b074c4e1bff
|
4
|
+
data.tar.gz: 08366d6b98a953349a1dff0e1585de45d3f4ff05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc9ae556196bbb405d1524d55b770a67b4b68647fc54332636e01b65e325221158cbb90bfd4868d47e7a6c8d86f267e507da0bb9213aff7c0322d8943214096f
|
7
|
+
data.tar.gz: 63b2478668b5f76a29b4c72beffa227402eedd5671a9b4da7ad88a748373847e6ae5c181b64c0ec692c637c3914313e2731919e8356f0b03e33e3733313a13a1
|
data/.travis.yml
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
4
|
-
- 2.2
|
3
|
+
- 2.2.4
|
5
4
|
- jruby
|
6
5
|
gemfile:
|
7
6
|
- Gemfile
|
8
|
-
- gemfiles/activerecord31.gemfile
|
9
|
-
- gemfiles/activerecord32.gemfile
|
10
|
-
- gemfiles/activerecord40.gemfile
|
11
|
-
- gemfiles/activerecord41.gemfile
|
7
|
+
- test/gemfiles/activerecord31.gemfile
|
8
|
+
- test/gemfiles/activerecord32.gemfile
|
9
|
+
- test/gemfiles/activerecord40.gemfile
|
10
|
+
- test/gemfiles/activerecord41.gemfile
|
11
|
+
- test/gemfiles/activerecord50.gemfile
|
12
|
+
sudo: false
|
12
13
|
script: bundle exec rake test
|
13
|
-
|
14
|
+
before_install:
|
15
|
+
- gem install bundler
|
14
16
|
- mysql -e 'create database groupdate_test;'
|
15
17
|
- mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
|
16
18
|
- psql -c 'create database groupdate_test;' -U postgres
|
@@ -22,3 +24,4 @@ matrix:
|
|
22
24
|
allow_failures:
|
23
25
|
- rvm: jruby
|
24
26
|
gemfile: Gemfile
|
27
|
+
- gemfile: test/gemfiles/activerecord50.gemfile
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -41,6 +41,7 @@ You can also group by:
|
|
41
41
|
- hour
|
42
42
|
- week
|
43
43
|
- month
|
44
|
+
- quarter
|
44
45
|
- year
|
45
46
|
|
46
47
|
and
|
@@ -140,10 +141,10 @@ User.group_by_day(:created_at).order("day desc").count
|
|
140
141
|
To get keys in a different format, use:
|
141
142
|
|
142
143
|
```ruby
|
143
|
-
User.
|
144
|
+
User.group_by_month(:created_at, format: "%b %Y").count
|
144
145
|
# {
|
145
|
-
# "Jan
|
146
|
-
# "
|
146
|
+
# "Jan 2015" => 10
|
147
|
+
# "Feb 2015" => 12
|
147
148
|
# }
|
148
149
|
```
|
149
150
|
|
@@ -158,7 +159,7 @@ User.group_by_hour_of_day(:created_at, format: "%-l %P").count
|
|
158
159
|
# }
|
159
160
|
```
|
160
161
|
|
161
|
-
Takes a `String`, which is passed to [strftime](http://strfti.me/), or a `Proc`. You can pass a locale with the `locale` option.
|
162
|
+
Takes a `String`, which is passed to [strftime](http://strfti.me/), or a `Symbol`, which is looked up by `I18n.localize` in `i18n` scope 'time.formats', or a `Proc`. You can pass a locale with the `locale` option.
|
162
163
|
|
163
164
|
### Dynamic Grouping
|
164
165
|
|
data/Rakefile
CHANGED
data/lib/groupdate.rb
CHANGED
@@ -4,8 +4,10 @@ require "groupdate/version"
|
|
4
4
|
require "groupdate/magic"
|
5
5
|
|
6
6
|
module Groupdate
|
7
|
-
|
8
|
-
|
7
|
+
PERIODS = [:second, :minute, :hour, :day, :week, :month, :quarter, :year, :day_of_week, :hour_of_day, :day_of_month, :month_of_year]
|
8
|
+
# backwards compatibility for anyone who happened to use it
|
9
|
+
FIELDS = PERIODS
|
10
|
+
METHODS = PERIODS.map { |v| :"group_by_#{v}" }
|
9
11
|
|
10
12
|
mattr_accessor :week_start, :day_start, :time_zone
|
11
13
|
self.week_start = :sun
|
@@ -26,25 +26,27 @@ module ActiveRecord
|
|
26
26
|
module Associations
|
27
27
|
class CollectionProxy
|
28
28
|
if ActiveRecord::VERSION::MAJOR == 3
|
29
|
-
delegate *Groupdate::METHODS, :
|
29
|
+
delegate *Groupdate::METHODS, to: :scoped
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
# hack for
|
35
|
+
# hack for issue before Rails 5
|
36
36
|
# https://github.com/rails/rails/issues/7121
|
37
37
|
module ActiveRecord
|
38
38
|
module Calculations
|
39
39
|
private
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
keys.first.
|
44
|
-
|
45
|
-
|
41
|
+
if ActiveRecord::VERSION::MAJOR < 5
|
42
|
+
def column_alias_for_with_hack(*keys)
|
43
|
+
if keys.first.is_a?(Groupdate::OrderHack)
|
44
|
+
keys.first.field
|
45
|
+
else
|
46
|
+
column_alias_for_without_hack(*keys)
|
47
|
+
end
|
46
48
|
end
|
49
|
+
alias_method_chain :column_alias_for, :hack
|
47
50
|
end
|
48
|
-
alias_method_chain :column_alias_for, :hack
|
49
51
|
end
|
50
52
|
end
|
data/lib/groupdate/enumerable.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module Enumerable
|
2
|
-
Groupdate::
|
3
|
-
define_method :"group_by_#{
|
2
|
+
Groupdate::PERIODS.each do |period|
|
3
|
+
define_method :"group_by_#{period}" do |*args, &block|
|
4
4
|
if block
|
5
|
-
Groupdate::Magic.new(
|
5
|
+
Groupdate::Magic.new(period, args[0] || {}).group_by(self, &block)
|
6
|
+
elsif respond_to?(:scoping)
|
7
|
+
scoping { @klass.send(:"group_by_#{period}", *args, &block) }
|
6
8
|
else
|
7
9
|
raise ArgumentError, "no block given"
|
8
10
|
end
|
@@ -11,7 +13,7 @@ module Enumerable
|
|
11
13
|
|
12
14
|
def group_by_period(period, options = {}, &block)
|
13
15
|
# to_sym is unsafe on user input, so convert to strings
|
14
|
-
permitted_periods = ((options[:permit] || Groupdate::
|
16
|
+
permitted_periods = ((options[:permit] || Groupdate::PERIODS).map(&:to_sym) & Groupdate::PERIODS).map(&:to_s)
|
15
17
|
if permitted_periods.include?(period.to_s)
|
16
18
|
send("group_by_#{period}", options, &block)
|
17
19
|
else
|
data/lib/groupdate/magic.rb
CHANGED
@@ -8,13 +8,9 @@ module Groupdate
|
|
8
8
|
@field = field
|
9
9
|
@options = options
|
10
10
|
|
11
|
-
unless time_zone
|
12
|
-
raise "Unrecognized time zone"
|
13
|
-
end
|
11
|
+
raise "Unrecognized time zone" unless time_zone
|
14
12
|
|
15
|
-
if field == :week && !week_start
|
16
|
-
raise "Unrecognized :week_start option"
|
17
|
-
end
|
13
|
+
raise "Unrecognized :week_start option" if field == :week && !week_start
|
18
14
|
end
|
19
15
|
|
20
16
|
def group_by(enum, &_block)
|
@@ -36,7 +32,7 @@ module Groupdate
|
|
36
32
|
adapter_name = relation.connection.adapter_name
|
37
33
|
query =
|
38
34
|
case adapter_name
|
39
|
-
when "MySQL", "Mysql2"
|
35
|
+
when "MySQL", "Mysql2", "Mysql2Spatial"
|
40
36
|
case field
|
41
37
|
when :day_of_week # Sunday = 0, Monday = 1, etc
|
42
38
|
# use CONCAT for consistent return type (String)
|
@@ -49,6 +45,8 @@ module Groupdate
|
|
49
45
|
["MONTH(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} HOUR), '+00:00', ?))", time_zone]
|
50
46
|
when :week
|
51
47
|
["CONVERT_TZ(DATE_FORMAT(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL ((#{7 - week_start} + WEEKDAY(CONVERT_TZ(#{column}, '+00:00', ?) - INTERVAL #{day_start} HOUR)) % 7) DAY) - INTERVAL #{day_start} HOUR, '+00:00', ?), '%Y-%m-%d 00:00:00') + INTERVAL #{day_start} HOUR, ?, '+00:00')", time_zone, time_zone, time_zone]
|
48
|
+
when :quarter
|
49
|
+
["DATE_ADD(CONVERT_TZ(DATE_FORMAT(DATE(CONCAT(EXTRACT(YEAR FROM CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} HOUR), '+00:00', ?)), '-', LPAD(1 + 3 * (QUARTER(CONVERT_TZ(DATE_SUB(#{column}, INTERVAL #{day_start} HOUR), '+00:00', ?)) - 1), 2, '00'), '-01')), '%Y-%m-%d %H:%i:%S'), ?, '+00:00'), INTERVAL #{day_start} HOUR)", time_zone, time_zone, time_zone]
|
52
50
|
else
|
53
51
|
format =
|
54
52
|
case field
|
@@ -109,9 +107,7 @@ module Groupdate
|
|
109
107
|
def perform(relation, method, *args, &block)
|
110
108
|
# undo reverse since we do not want this to appear in the query
|
111
109
|
reverse = relation.send(:reverse_order_value)
|
112
|
-
if reverse
|
113
|
-
relation = relation.except(:reverse_order)
|
114
|
-
end
|
110
|
+
relation = relation.except(:reverse_order) if reverse
|
115
111
|
order = relation.order_values.first
|
116
112
|
if order.is_a?(String)
|
117
113
|
parts = order.split(" ")
|
@@ -140,7 +136,7 @@ module Groupdate
|
|
140
136
|
raise "Be sure to install time zone support - https://github.com/ankane/groupdate#for-mysql"
|
141
137
|
end
|
142
138
|
|
143
|
-
series(count, 0, multiple_groups, reverse)
|
139
|
+
series(count, (options.key?(:default_value) ? options[:default_value] : 0), multiple_groups, reverse)
|
144
140
|
end
|
145
141
|
|
146
142
|
protected
|
@@ -207,7 +203,11 @@ module Groupdate
|
|
207
203
|
if time_range.first
|
208
204
|
series = [round_time(time_range.first)]
|
209
205
|
|
210
|
-
|
206
|
+
if field == :quarter
|
207
|
+
step = 3.months
|
208
|
+
else
|
209
|
+
step = 1.send(field)
|
210
|
+
end
|
211
211
|
|
212
212
|
while (next_step = round_time(series.last + step)) && time_range.cover?(next_step)
|
213
213
|
series << next_step
|
@@ -231,9 +231,7 @@ module Groupdate
|
|
231
231
|
end
|
232
232
|
|
233
233
|
# reversed above if multiple groups
|
234
|
-
if !multiple_groups && reverse
|
235
|
-
series = series.to_a.reverse
|
236
|
-
end
|
234
|
+
series = series.to_a.reverse if !multiple_groups && reverse
|
237
235
|
|
238
236
|
locale = options[:locale] || I18n.locale
|
239
237
|
key_format =
|
@@ -253,7 +251,7 @@ module Groupdate
|
|
253
251
|
when :month_of_year
|
254
252
|
key = Date.new(2014, key, 1).to_time
|
255
253
|
end
|
256
|
-
I18n.localize(key, format: options[:format]
|
254
|
+
I18n.localize(key, format: options[:format], locale: locale)
|
257
255
|
end
|
258
256
|
end
|
259
257
|
else
|
@@ -273,11 +271,11 @@ module Groupdate
|
|
273
271
|
time =
|
274
272
|
case field
|
275
273
|
when :second
|
276
|
-
time.change(:
|
274
|
+
time.change(usec: 0)
|
277
275
|
when :minute
|
278
|
-
time.change(:
|
276
|
+
time.change(sec: 0)
|
279
277
|
when :hour
|
280
|
-
time.change(:
|
278
|
+
time.change(min: 0)
|
281
279
|
when :day
|
282
280
|
time.beginning_of_day
|
283
281
|
when :week
|
@@ -286,6 +284,8 @@ module Groupdate
|
|
286
284
|
(time - ((7 - week_start + weekday) % 7).days).midnight
|
287
285
|
when :month
|
288
286
|
time.beginning_of_month
|
287
|
+
when :quarter
|
288
|
+
time.beginning_of_quarter
|
289
289
|
when :year
|
290
290
|
time.beginning_of_year
|
291
291
|
when :hour_of_day
|
data/lib/groupdate/scopes.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
module Groupdate
|
2
2
|
module Scopes
|
3
|
-
Groupdate::
|
4
|
-
define_method :"group_by_#{
|
3
|
+
Groupdate::PERIODS.each do |period|
|
4
|
+
define_method :"group_by_#{period}" do |field, *args|
|
5
5
|
args = args.dup
|
6
6
|
options = args[-1].is_a?(Hash) ? args.pop : {}
|
7
|
-
options[:time_zone] ||= args[
|
8
|
-
options[:range] ||= args[
|
7
|
+
options[:time_zone] ||= args[0] unless args[0].nil?
|
8
|
+
options[:range] ||= args[1] unless args[1].nil?
|
9
9
|
|
10
|
-
Groupdate::Magic.new(
|
10
|
+
Groupdate::Magic.new(period, options).relation(field, self)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
def group_by_period(period, field, options = {})
|
15
15
|
# to_sym is unsafe on user input, so convert to strings
|
16
|
-
permitted_periods = ((options[:permit] || Groupdate::
|
16
|
+
permitted_periods = ((options[:permit] || Groupdate::PERIODS).map(&:to_sym) & Groupdate::PERIODS).map(&:to_s)
|
17
17
|
if permitted_periods.include?(period.to_s)
|
18
18
|
send("group_by_#{period}", field, options)
|
19
19
|
else
|
data/lib/groupdate/version.rb
CHANGED
data/test/mysql_test.rb
CHANGED
data/test/postgresql_test.rb
CHANGED
@@ -5,6 +5,10 @@ class TestPostgresql < Minitest::Test
|
|
5
5
|
|
6
6
|
def setup
|
7
7
|
super
|
8
|
-
User.establish_connection :
|
8
|
+
User.establish_connection adapter: "postgresql", database: "groupdate_test"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_no_column
|
12
|
+
assert_raises(ArgumentError) { User.group_by_day.first }
|
9
13
|
end
|
10
14
|
end
|
data/test/test_helper.rb
CHANGED
@@ -24,21 +24,24 @@ end
|
|
24
24
|
|
25
25
|
# i18n
|
26
26
|
I18n.enforce_available_locales = true
|
27
|
-
I18n.backend.store_translations :de, :
|
28
|
-
:
|
27
|
+
I18n.backend.store_translations :de, date: {
|
28
|
+
abbr_month_names: %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
|
29
|
+
},
|
30
|
+
time: {
|
31
|
+
formats: {special: "%b %e, %Y"}
|
29
32
|
}
|
30
33
|
|
31
34
|
# migrations
|
32
35
|
%w(postgresql mysql2).each do |adapter|
|
33
|
-
ActiveRecord::Base.establish_connection :
|
36
|
+
ActiveRecord::Base.establish_connection adapter: adapter, database: "groupdate_test", username: adapter == "mysql2" ? "root" : nil
|
34
37
|
|
35
|
-
ActiveRecord::Migration.create_table :users, :
|
38
|
+
ActiveRecord::Migration.create_table :users, force: true do |t|
|
36
39
|
t.string :name
|
37
40
|
t.integer :score
|
38
41
|
t.timestamp :created_at
|
39
42
|
end
|
40
43
|
|
41
|
-
ActiveRecord::Migration.create_table :posts, :
|
44
|
+
ActiveRecord::Migration.create_table :posts, force: true do |t|
|
42
45
|
t.references :user
|
43
46
|
t.timestamp :created_at
|
44
47
|
end
|
@@ -104,19 +107,19 @@ module TestGroupdate
|
|
104
107
|
# day hour starts at 2 am
|
105
108
|
|
106
109
|
def test_test_day_end_of_day_day_start_2am
|
107
|
-
assert_result_time :day, "2013-05-03 02:00:00 UTC", "2013-05-04 01:59:59", false, :
|
110
|
+
assert_result_time :day, "2013-05-03 02:00:00 UTC", "2013-05-04 01:59:59", false, day_start: 2
|
108
111
|
end
|
109
112
|
|
110
113
|
def test_test_day_start_of_day_day_start_2am
|
111
|
-
assert_result_time :day, "2013-05-03 02:00:00 UTC", "2013-05-03 02:00:00", false, :
|
114
|
+
assert_result_time :day, "2013-05-03 02:00:00 UTC", "2013-05-03 02:00:00", false, day_start: 2
|
112
115
|
end
|
113
116
|
|
114
117
|
def test_test_day_end_of_day_with_time_zone_day_start_2am
|
115
|
-
assert_result_time :day, "2013-05-03 02:00:00 PDT", "2013-05-04 07:59:59", true, :
|
118
|
+
assert_result_time :day, "2013-05-03 02:00:00 PDT", "2013-05-04 07:59:59", true, day_start: 2
|
116
119
|
end
|
117
120
|
|
118
121
|
def test_test_day_start_of_day_with_time_zone_day_start_2am
|
119
|
-
assert_result_time :day, "2013-05-03 02:00:00 PDT", "2013-05-03 09:00:00", true, :
|
122
|
+
assert_result_time :day, "2013-05-03 02:00:00 PDT", "2013-05-03 09:00:00", true, day_start: 2
|
120
123
|
end
|
121
124
|
|
122
125
|
# week
|
@@ -176,19 +179,19 @@ module TestGroupdate
|
|
176
179
|
# week starting at 2am
|
177
180
|
|
178
181
|
def test_week_end_of_week_day_start_2am
|
179
|
-
assert_result_time :week, "2013-03-17 02:00:00 UTC", "2013-03-24 01:59:59", false, :
|
182
|
+
assert_result_time :week, "2013-03-17 02:00:00 UTC", "2013-03-24 01:59:59", false, day_start: 2
|
180
183
|
end
|
181
184
|
|
182
185
|
def test_week_start_of_week_day_start_2am
|
183
|
-
assert_result_time :week, "2013-03-17 02:00:00 UTC", "2013-03-17 02:00:00", false, :
|
186
|
+
assert_result_time :week, "2013-03-17 02:00:00 UTC", "2013-03-17 02:00:00", false, day_start: 2
|
184
187
|
end
|
185
188
|
|
186
189
|
def test_week_end_of_week_day_with_time_zone_start_2am
|
187
|
-
assert_result_time :week, "2013-03-17 02:00:00 PDT", "2013-03-24 08:59:59", true, :
|
190
|
+
assert_result_time :week, "2013-03-17 02:00:00 PDT", "2013-03-24 08:59:59", true, day_start: 2
|
188
191
|
end
|
189
192
|
|
190
193
|
def test_week_start_of_week_day_with_time_zone_start_2am
|
191
|
-
assert_result_time :week, "2013-03-17 02:00:00 PDT", "2013-03-17 09:00:00", true, :
|
194
|
+
assert_result_time :week, "2013-03-17 02:00:00 PDT", "2013-03-17 09:00:00", true, day_start: 2
|
192
195
|
end
|
193
196
|
|
194
197
|
# month
|
@@ -212,19 +215,55 @@ module TestGroupdate
|
|
212
215
|
# month starts at 2am
|
213
216
|
|
214
217
|
def test_month_end_of_month_day_start_2am
|
215
|
-
assert_result_time :month, "2013-03-01 02:00:00 UTC", "2013-04-01 01:59:59", false, :
|
218
|
+
assert_result_time :month, "2013-03-01 02:00:00 UTC", "2013-04-01 01:59:59", false, day_start: 2
|
216
219
|
end
|
217
220
|
|
218
221
|
def test_month_start_of_month_day_start_2am
|
219
|
-
assert_result_time :month, "2013-03-01 02:00:00 UTC", "2013-03-01 02:00:00", false, :
|
222
|
+
assert_result_time :month, "2013-03-01 02:00:00 UTC", "2013-03-01 02:00:00", false, day_start: 2
|
220
223
|
end
|
221
224
|
|
222
225
|
def test_month_end_of_month_with_time_zone_day_start_2am
|
223
|
-
assert_result_time :month, "2013-03-01 02:00:00 PST", "2013-04-01 08:59:59", true, :
|
226
|
+
assert_result_time :month, "2013-03-01 02:00:00 PST", "2013-04-01 08:59:59", true, day_start: 2
|
224
227
|
end
|
225
228
|
|
226
229
|
def test_month_start_of_month_with_time_zone_day_start_2am
|
227
|
-
assert_result_time :month, "2013-03-01 02:00:00 PST", "2013-03-01 10:00:00", true, :
|
230
|
+
assert_result_time :month, "2013-03-01 02:00:00 PST", "2013-03-01 10:00:00", true, day_start: 2
|
231
|
+
end
|
232
|
+
|
233
|
+
# quarter
|
234
|
+
|
235
|
+
def test_quarter_end_of_quarter
|
236
|
+
assert_result_time :quarter, "2013-04-01 00:00:00 UTC", "2013-06-30 23:59:59"
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_quarter_start_of_quarter
|
240
|
+
assert_result_time :quarter, "2013-04-01 00:00:00 UTC", "2013-04-01 00:00:00"
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_quarter_end_of_quarter_with_time_zone
|
244
|
+
assert_result_time :quarter, "2013-04-01 00:00:00 PDT", "2013-07-01 06:59:59", true
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_quarter_start_of_quarter_with_time_zone
|
248
|
+
assert_result_time :quarter, "2013-04-01 00:00:00 PDT", "2013-04-01 07:00:00", true
|
249
|
+
end
|
250
|
+
|
251
|
+
# quarter starts at 2am
|
252
|
+
|
253
|
+
def test_quarter_end_of_quarter_day_start_2am
|
254
|
+
assert_result_time :quarter, "2013-04-01 02:00:00 UTC", "2013-07-01 01:59:59", false, day_start: 2
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_quarter_start_of_quarter_day_start_2am
|
258
|
+
assert_result_time :quarter, "2013-04-01 02:00:00 UTC", "2013-04-01 02:00:00", false, day_start: 2
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_quarter_end_of_quarter_with_time_zone_day_start_2am
|
262
|
+
assert_result_time :quarter, "2013-01-01 02:00:00 PST", "2013-04-01 08:59:59", true, day_start: 2
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_quarter_start_of_quarter_with_time_zone_day_start_2am
|
266
|
+
assert_result_time :quarter, "2013-01-01 02:00:00 PST", "2013-01-01 10:00:00", true, day_start: 2
|
228
267
|
end
|
229
268
|
|
230
269
|
# year
|
@@ -248,19 +287,19 @@ module TestGroupdate
|
|
248
287
|
# year starts at 2am
|
249
288
|
|
250
289
|
def test_year_end_of_year_day_start_2am
|
251
|
-
assert_result_time :year, "2013-01-01 02:00:00 UTC", "2014-01-01 01:59:59", false, :
|
290
|
+
assert_result_time :year, "2013-01-01 02:00:00 UTC", "2014-01-01 01:59:59", false, day_start: 2
|
252
291
|
end
|
253
292
|
|
254
293
|
def test_year_start_of_year_day_start_2am
|
255
|
-
assert_result_time :year, "2013-01-01 02:00:00 UTC", "2013-01-01 02:00:00", false, :
|
294
|
+
assert_result_time :year, "2013-01-01 02:00:00 UTC", "2013-01-01 02:00:00", false, day_start: 2
|
256
295
|
end
|
257
296
|
|
258
297
|
def test_year_end_of_year_with_time_zone_day_start_2am
|
259
|
-
assert_result_time :year, "2013-01-01 02:00:00 PST", "2014-01-01 09:59:59", true, :
|
298
|
+
assert_result_time :year, "2013-01-01 02:00:00 PST", "2014-01-01 09:59:59", true, day_start: 2
|
260
299
|
end
|
261
300
|
|
262
301
|
def test_year_start_of_year_with_time_zone_day_start_2am
|
263
|
-
assert_result_time :year, "2013-01-01 02:00:00 PST", "2013-01-01 10:00:00", true, :
|
302
|
+
assert_result_time :year, "2013-01-01 02:00:00 PST", "2013-01-01 10:00:00", true, day_start: 2
|
264
303
|
end
|
265
304
|
|
266
305
|
# hour of day
|
@@ -284,19 +323,19 @@ module TestGroupdate
|
|
284
323
|
# hour of day starts at 2am
|
285
324
|
|
286
325
|
def test_hour_of_day_end_of_day_day_start_2am
|
287
|
-
assert_result :hour_of_day, 23, "2013-01-01 01:59:59", false, :
|
326
|
+
assert_result :hour_of_day, 23, "2013-01-01 01:59:59", false, day_start: 2
|
288
327
|
end
|
289
328
|
|
290
329
|
def test_hour_of_day_start_of_day_day_start_2am
|
291
|
-
assert_result :hour_of_day, 0, "2013-01-01 02:00:00", false, :
|
330
|
+
assert_result :hour_of_day, 0, "2013-01-01 02:00:00", false, day_start: 2
|
292
331
|
end
|
293
332
|
|
294
333
|
def test_hour_of_day_end_of_day_with_time_zone_day_start_2am
|
295
|
-
assert_result :hour_of_day, 23, "2013-01-01 09:59:59", true, :
|
334
|
+
assert_result :hour_of_day, 23, "2013-01-01 09:59:59", true, day_start: 2
|
296
335
|
end
|
297
336
|
|
298
337
|
def test_hour_of_day_start_of_day_with_time_zone_day_start_2am
|
299
|
-
assert_result :hour_of_day, 0, "2013-01-01 10:00:00", true, :
|
338
|
+
assert_result :hour_of_day, 0, "2013-01-01 10:00:00", true, day_start: 2
|
300
339
|
end
|
301
340
|
|
302
341
|
# day of week
|
@@ -320,19 +359,19 @@ module TestGroupdate
|
|
320
359
|
# day of week starts at 2am
|
321
360
|
|
322
361
|
def test_day_of_week_end_of_day_day_start_2am
|
323
|
-
assert_result :day_of_week, 3, "2013-01-03 01:59:59", false, :
|
362
|
+
assert_result :day_of_week, 3, "2013-01-03 01:59:59", false, day_start: 2
|
324
363
|
end
|
325
364
|
|
326
365
|
def test_day_of_week_start_of_day_day_start_2am
|
327
|
-
assert_result :day_of_week, 3, "2013-01-02 02:00:00", false, :
|
366
|
+
assert_result :day_of_week, 3, "2013-01-02 02:00:00", false, day_start: 2
|
328
367
|
end
|
329
368
|
|
330
369
|
def test_day_of_week_end_of_day_with_time_zone_day_start_2am
|
331
|
-
assert_result :day_of_week, 3, "2013-01-03 09:59:59", true, :
|
370
|
+
assert_result :day_of_week, 3, "2013-01-03 09:59:59", true, day_start: 2
|
332
371
|
end
|
333
372
|
|
334
373
|
def test_day_of_week_start_of_day_with_time_zone_day_start_2am
|
335
|
-
assert_result :day_of_week, 3, "2013-01-02 10:00:00", true, :
|
374
|
+
assert_result :day_of_week, 3, "2013-01-02 10:00:00", true, day_start: 2
|
336
375
|
end
|
337
376
|
|
338
377
|
# day of month
|
@@ -360,19 +399,19 @@ module TestGroupdate
|
|
360
399
|
# day of month starts at 2am
|
361
400
|
|
362
401
|
def test_day_of_month_end_of_day_day_start_2am
|
363
|
-
assert_result :day_of_month, 31, "2013-01-01 01:59:59", false, :
|
402
|
+
assert_result :day_of_month, 31, "2013-01-01 01:59:59", false, day_start: 2
|
364
403
|
end
|
365
404
|
|
366
405
|
def test_day_of_month_start_of_day_day_start_2am
|
367
|
-
assert_result :day_of_month, 1, "2013-01-01 02:00:00", false, :
|
406
|
+
assert_result :day_of_month, 1, "2013-01-01 02:00:00", false, day_start: 2
|
368
407
|
end
|
369
408
|
|
370
409
|
def test_day_of_month_end_of_day_with_time_zone_day_start_2am
|
371
|
-
assert_result :day_of_month, 31, "2013-01-01 09:59:59", true, :
|
410
|
+
assert_result :day_of_month, 31, "2013-01-01 09:59:59", true, day_start: 2
|
372
411
|
end
|
373
412
|
|
374
413
|
def test_day_of_month_start_of_day_with_time_zone_day_start_2am
|
375
|
-
assert_result :day_of_month, 1, "2013-01-01 10:00:00", true, :
|
414
|
+
assert_result :day_of_month, 1, "2013-01-01 10:00:00", true, day_start: 2
|
376
415
|
end
|
377
416
|
|
378
417
|
# month of year
|
@@ -396,19 +435,19 @@ module TestGroupdate
|
|
396
435
|
# month of year starts at 2am
|
397
436
|
|
398
437
|
def test_month_of_year_end_of_month_day_start_2am
|
399
|
-
assert_result :month_of_year, 12, "2013-01-01 01:59:59", false, :
|
438
|
+
assert_result :month_of_year, 12, "2013-01-01 01:59:59", false, day_start: 2
|
400
439
|
end
|
401
440
|
|
402
441
|
def test_month_of_year_start_of_month_day_start_2am
|
403
|
-
assert_result :month_of_year, 1, "2013-01-01 02:00:00", false, :
|
442
|
+
assert_result :month_of_year, 1, "2013-01-01 02:00:00", false, day_start: 2
|
404
443
|
end
|
405
444
|
|
406
445
|
def test_month_of_year_end_of_month_with_time_zone_day_start_2am
|
407
|
-
assert_result :month_of_year, 12, "2013-01-01 09:59:59", true, :
|
446
|
+
assert_result :month_of_year, 12, "2013-01-01 09:59:59", true, day_start: 2
|
408
447
|
end
|
409
448
|
|
410
449
|
def test_month_of_year_start_of_month_with_time_zone_day_start_2am
|
411
|
-
assert_result :month_of_year, 1, "2013-01-01 10:00:00", true, :
|
450
|
+
assert_result :month_of_year, 1, "2013-01-01 10:00:00", true, day_start: 2
|
412
451
|
end
|
413
452
|
|
414
453
|
# zeros
|
@@ -465,6 +504,14 @@ module TestGroupdate
|
|
465
504
|
assert_zeros :month, "2013-04-16 20:00:00 PDT", ["2013-03-01 00:00:00 PST", "2013-04-01 00:00:00 PDT", "2013-05-01 00:00:00 PDT"], "2013-03-01 00:00:00 PST", "2013-05-31 23:59:59 PDT", true
|
466
505
|
end
|
467
506
|
|
507
|
+
def test_zeros_quarter
|
508
|
+
assert_zeros :quarter, "2013-04-16 20:00:00 UTC", ["2013-01-01 00:00:00 UTC", "2013-04-01 00:00:00 UTC", "2013-07-01 00:00:00 UTC"], "2013-01-01 00:00:00 UTC", "2013-09-30 23:59:59 UTC"
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_zeros_quarter_time_zone
|
512
|
+
assert_zeros :quarter, "2013-04-16 20:00:00 PDT", ["2013-01-01 00:00:00 PST", "2013-04-01 00:00:00 PDT", "2013-07-01 00:00:00 PDT"], "2013-01-01 00:00:00 PST", "2013-09-30 23:59:59 PDT", true
|
513
|
+
end
|
514
|
+
|
468
515
|
def test_zeros_year
|
469
516
|
assert_zeros :year, "2013-04-16 20:00:00 UTC", ["2012-01-01 00:00:00 UTC", "2013-01-01 00:00:00 UTC", "2014-01-01 00:00:00 UTC"], "2012-01-01 00:00:00 UTC", "2014-12-31 23:59:59 UTC"
|
470
517
|
end
|
@@ -573,10 +620,12 @@ module TestGroupdate
|
|
573
620
|
end
|
574
621
|
|
575
622
|
def test_order_hour_of_day_reverse
|
623
|
+
skip if ActiveRecord::VERSION::MAJOR == 5
|
576
624
|
assert_equal 23, User.group_by_hour_of_day(:created_at).reverse_order.count.keys.first
|
577
625
|
end
|
578
626
|
|
579
627
|
def test_order_hour_of_day_order_reverse
|
628
|
+
skip if ActiveRecord::VERSION::MAJOR == 5
|
580
629
|
assert_equal 0, User.group_by_hour_of_day(:created_at).order("hour_of_day desc").reverse_order.count.keys.first
|
581
630
|
end
|
582
631
|
|
@@ -688,22 +737,22 @@ module TestGroupdate
|
|
688
737
|
end
|
689
738
|
|
690
739
|
def test_last
|
691
|
-
create_user "
|
692
|
-
create_user "
|
740
|
+
create_user "#{this_year - 3}-01-01 00:00:00 UTC"
|
741
|
+
create_user "#{this_year - 1}-01-01 00:00:00 UTC"
|
693
742
|
expected = {
|
694
|
-
utc.parse("
|
695
|
-
utc.parse("
|
696
|
-
utc.parse("
|
743
|
+
utc.parse("#{this_year - 2}-01-01 00:00:00 UTC") => 0,
|
744
|
+
utc.parse("#{this_year - 1}-01-01 00:00:00 UTC") => 1,
|
745
|
+
utc.parse("#{this_year}-01-01 00:00:00 UTC") => 0
|
697
746
|
}
|
698
747
|
assert_equal expected, User.group_by_year(:created_at, last: 3).count
|
699
748
|
end
|
700
749
|
|
701
750
|
def test_current
|
702
|
-
create_user "
|
703
|
-
create_user "
|
751
|
+
create_user "#{this_year - 3}-01-01 00:00:00 UTC"
|
752
|
+
create_user "#{this_year - 1}-01-01 00:00:00 UTC"
|
704
753
|
expected = {
|
705
|
-
utc.parse("
|
706
|
-
utc.parse("
|
754
|
+
utc.parse("#{this_year - 2}-01-01 00:00:00 UTC") => 0,
|
755
|
+
utc.parse("#{this_year - 1}-01-01 00:00:00 UTC") => 1
|
707
756
|
}
|
708
757
|
assert_equal expected, User.group_by_year(:created_at, last: 2, current: false).count
|
709
758
|
end
|
@@ -718,6 +767,11 @@ module TestGroupdate
|
|
718
767
|
assert_format :month, "March 2014", "%B %Y"
|
719
768
|
end
|
720
769
|
|
770
|
+
def test_format_quarter
|
771
|
+
create_user "2014-03-05 00:00:00 UTC"
|
772
|
+
assert_format :quarter, "January 1, 2014", "%B %-e, %Y"
|
773
|
+
end
|
774
|
+
|
721
775
|
def test_format_year
|
722
776
|
create_user "2014-03-01 00:00:00 UTC"
|
723
777
|
assert_format :year, "2014", "%Y"
|
@@ -758,6 +812,11 @@ module TestGroupdate
|
|
758
812
|
assert_equal ({"Okt" => 1}), User.group_by_day(:created_at, format: "%b", locale: :de).count
|
759
813
|
end
|
760
814
|
|
815
|
+
def test_format_locale_by_symbol
|
816
|
+
create_user "2014-10-01 00:00:00 UTC"
|
817
|
+
assert_equal ({"Okt 1, 2014" => 1}), User.group_by_day(:created_at, format: :special, locale: :de).count
|
818
|
+
end
|
819
|
+
|
761
820
|
def test_format_locale_global
|
762
821
|
create_user "2014-10-01 00:00:00 UTC"
|
763
822
|
I18n.locale = :de
|
@@ -775,7 +834,7 @@ module TestGroupdate
|
|
775
834
|
# permit
|
776
835
|
|
777
836
|
def test_permit
|
778
|
-
assert_raises(ArgumentError, "Unpermitted period") { User.group_by_period(:day, :created_at, permit: %w
|
837
|
+
assert_raises(ArgumentError, "Unpermitted period") { User.group_by_period(:day, :created_at, permit: %w(week)).count }
|
779
838
|
end
|
780
839
|
|
781
840
|
def test_permit_bad_period
|
@@ -791,11 +850,22 @@ module TestGroupdate
|
|
791
850
|
end
|
792
851
|
|
793
852
|
def test_permit_symbol_strings
|
794
|
-
assert_equal ({}), User.group_by_period(:day, :created_at, permit: %w
|
853
|
+
assert_equal ({}), User.group_by_period(:day, :created_at, permit: %w(day)).count
|
795
854
|
end
|
796
855
|
|
797
856
|
def test_permit_string_strings
|
798
|
-
assert_equal ({}), User.group_by_period("day", :created_at, permit: %w
|
857
|
+
assert_equal ({}), User.group_by_period("day", :created_at, permit: %w(day)).count
|
858
|
+
end
|
859
|
+
|
860
|
+
# default value
|
861
|
+
|
862
|
+
def test_default_value
|
863
|
+
create_user "#{this_year}-01-01 00:00:00 UTC"
|
864
|
+
expected = {
|
865
|
+
utc.parse("#{this_year - 1}-01-01 00:00:00 UTC") => nil,
|
866
|
+
utc.parse("#{this_year}-01-01 00:00:00 UTC") => 1
|
867
|
+
}
|
868
|
+
assert_equal expected, User.group_by_year(:created_at, last: 2, default_value: nil).count
|
799
869
|
end
|
800
870
|
|
801
871
|
# associations
|
@@ -870,7 +940,11 @@ module TestGroupdate
|
|
870
940
|
end
|
871
941
|
|
872
942
|
def create_user(created_at, score = 1)
|
873
|
-
User.create! :
|
943
|
+
User.create! name: "Andrew", score: score, created_at: utc.parse(created_at)
|
944
|
+
end
|
945
|
+
|
946
|
+
def this_year
|
947
|
+
Time.now.utc.year
|
874
948
|
end
|
875
949
|
|
876
950
|
def utc
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: groupdate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -122,10 +122,6 @@ files:
|
|
122
122
|
- LICENSE.txt
|
123
123
|
- README.md
|
124
124
|
- Rakefile
|
125
|
-
- gemfiles/activerecord31.gemfile
|
126
|
-
- gemfiles/activerecord32.gemfile
|
127
|
-
- gemfiles/activerecord40.gemfile
|
128
|
-
- gemfiles/activerecord41.gemfile
|
129
125
|
- groupdate.gemspec
|
130
126
|
- lib/groupdate.rb
|
131
127
|
- lib/groupdate/active_record.rb
|
@@ -136,6 +132,11 @@ files:
|
|
136
132
|
- lib/groupdate/series.rb
|
137
133
|
- lib/groupdate/version.rb
|
138
134
|
- test/enumerable_test.rb
|
135
|
+
- test/gemfiles/activerecord31.gemfile
|
136
|
+
- test/gemfiles/activerecord32.gemfile
|
137
|
+
- test/gemfiles/activerecord40.gemfile
|
138
|
+
- test/gemfiles/activerecord41.gemfile
|
139
|
+
- test/gemfiles/activerecord50.gemfile
|
139
140
|
- test/mysql_test.rb
|
140
141
|
- test/postgresql_test.rb
|
141
142
|
- test/test_helper.rb
|
@@ -159,12 +160,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
159
160
|
version: '0'
|
160
161
|
requirements: []
|
161
162
|
rubyforge_project:
|
162
|
-
rubygems_version: 2.4.5
|
163
|
+
rubygems_version: 2.4.5.1
|
163
164
|
signing_key:
|
164
165
|
specification_version: 4
|
165
166
|
summary: The simplest way to group temporal data
|
166
167
|
test_files:
|
167
168
|
- test/enumerable_test.rb
|
169
|
+
- test/gemfiles/activerecord31.gemfile
|
170
|
+
- test/gemfiles/activerecord32.gemfile
|
171
|
+
- test/gemfiles/activerecord40.gemfile
|
172
|
+
- test/gemfiles/activerecord41.gemfile
|
173
|
+
- test/gemfiles/activerecord50.gemfile
|
168
174
|
- test/mysql_test.rb
|
169
175
|
- test/postgresql_test.rb
|
170
176
|
- test/test_helper.rb
|