groupdate 2.5.0 → 2.5.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/.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
|