groupdate 3.0.2 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -5
- data/CHANGELOG.md +5 -0
- data/README.md +8 -0
- data/lib/groupdate/active_record.rb +1 -0
- data/lib/groupdate/calculations.rb +26 -0
- data/lib/groupdate/magic.rb +9 -2
- data/lib/groupdate/series.rb +4 -4
- data/lib/groupdate/version.rb +1 -1
- data/test/test_helper.rb +84 -10
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87e6343538ca0aa70041863153b514d765952ca9
|
4
|
+
data.tar.gz: a5121f5bab5c8f9de575e5adcf09885c88abd08a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62c9cc55ca4f808911727d3513a50f79b379b041589b38a52214b9d87fe38d2d321ce6bb4d41a7b0fc9a8fc9a780f039d626582ce71cd65fdfe81467ac1a9107
|
7
|
+
data.tar.gz: b0dd02d55c7f72247e1bb5c7b9f221cddd4321fcb4e77d2101b9b759948e145385987e938134d5888ee95864066fbb943aae7a6226b7bc26fc334ffb6c219402
|
data/.travis.yml
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
3
|
- 2.2.4
|
4
|
-
- jruby
|
4
|
+
- jruby-9.1.5.0
|
5
5
|
gemfile:
|
6
6
|
- Gemfile
|
7
|
-
- test/gemfiles/activerecord31.gemfile
|
8
7
|
- test/gemfiles/activerecord32.gemfile
|
9
8
|
- test/gemfiles/activerecord40.gemfile
|
10
9
|
- test/gemfiles/activerecord41.gemfile
|
@@ -22,7 +21,5 @@ notifications:
|
|
22
21
|
on_failure: change
|
23
22
|
matrix:
|
24
23
|
allow_failures:
|
25
|
-
- rvm: jruby
|
24
|
+
- rvm: jruby-9.1.5.0
|
26
25
|
gemfile: Gemfile
|
27
|
-
- rvm: jruby
|
28
|
-
gemfile: test/gemfiles/activerecord42.gemfile
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -190,6 +190,14 @@ User.group_by_period(params[:period], :created_at, permit: %w[day week]).count
|
|
190
190
|
|
191
191
|
Raises an `ArgumentError` for unpermitted periods.
|
192
192
|
|
193
|
+
### Date Columns
|
194
|
+
|
195
|
+
If grouping on date columns which don’t need time zone conversion, use:
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
User.group_by_week(:created_on, time_zone: false).count
|
199
|
+
```
|
200
|
+
|
193
201
|
## Arrays and Hashes
|
194
202
|
|
195
203
|
```ruby
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Groupdate
|
2
|
+
class Calculations
|
3
|
+
attr_reader :relation
|
4
|
+
|
5
|
+
def initialize(relation)
|
6
|
+
@relation = relation
|
7
|
+
end
|
8
|
+
|
9
|
+
def include?(method)
|
10
|
+
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb
|
11
|
+
ActiveRecord::Calculations.method_defined?(method) || custom_calculations.include?(method)
|
12
|
+
end
|
13
|
+
|
14
|
+
def custom_calculations
|
15
|
+
return [] if !model.respond_to?(:groupdate_calculation_methods)
|
16
|
+
model.groupdate_calculation_methods
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def model
|
22
|
+
return if !relation.respond_to?(:klass)
|
23
|
+
relation.klass
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/groupdate/magic.rb
CHANGED
@@ -158,7 +158,8 @@ module Groupdate
|
|
158
158
|
|
159
159
|
def time_zone
|
160
160
|
@time_zone ||= begin
|
161
|
-
time_zone = options[:time_zone]
|
161
|
+
time_zone = "Etc/UTC" if options[:time_zone] == false
|
162
|
+
time_zone ||= options[:time_zone] || Groupdate.time_zone || Time.zone || "Etc/UTC"
|
162
163
|
time_zone.is_a?(ActiveSupport::TimeZone) ? time_zone : ActiveSupport::TimeZone[time_zone]
|
163
164
|
end
|
164
165
|
end
|
@@ -174,7 +175,13 @@ module Groupdate
|
|
174
175
|
def time_range
|
175
176
|
@time_range ||= begin
|
176
177
|
time_range = options[:range]
|
177
|
-
if
|
178
|
+
if time_range.is_a?(Range) && time_range.first.is_a?(Date)
|
179
|
+
# convert range of dates to range of times
|
180
|
+
# use parsing instead of in_time_zone due to Rails < 4
|
181
|
+
last = time_zone.parse(time_range.last.to_s)
|
182
|
+
last += 1.day unless time_range.exclude_end?
|
183
|
+
time_range = Range.new(time_zone.parse(time_range.first.to_s), last, true)
|
184
|
+
elsif !time_range && options[:last]
|
178
185
|
step = 1.send(field) if 1.respond_to?(field)
|
179
186
|
if step
|
180
187
|
now = Time.now
|
data/lib/groupdate/series.rb
CHANGED
@@ -5,14 +5,14 @@ module Groupdate
|
|
5
5
|
def initialize(magic, relation)
|
6
6
|
@magic = magic
|
7
7
|
@relation = relation
|
8
|
+
@calculations = Groupdate::Calculations.new(relation)
|
8
9
|
end
|
9
10
|
|
10
11
|
# clone to prevent modifying original variables
|
11
12
|
def method_missing(method, *args, &block)
|
12
|
-
|
13
|
-
if ActiveRecord::Calculations.method_defined?(method)
|
13
|
+
if @calculations.include?(method)
|
14
14
|
magic.perform(relation, method, *args, &block)
|
15
|
-
elsif
|
15
|
+
elsif relation.respond_to?(method, true)
|
16
16
|
Groupdate::Series.new(magic, relation.send(method, *args, &block))
|
17
17
|
else
|
18
18
|
super
|
@@ -20,7 +20,7 @@ module Groupdate
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def respond_to?(method, include_all = false)
|
23
|
-
|
23
|
+
@calculations.include?(method) || relation.respond_to?(method) || super
|
24
24
|
end
|
25
25
|
|
26
26
|
def reverse_order_value
|
data/lib/groupdate/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -18,6 +18,18 @@ ActiveRecord::Base.time_zone_aware_attributes = true
|
|
18
18
|
|
19
19
|
class User < ActiveRecord::Base
|
20
20
|
has_many :posts
|
21
|
+
|
22
|
+
def self.groupdate_calculation_methods
|
23
|
+
[:custom_count, :undefined_calculation]
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.custom_count
|
27
|
+
count
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.unlisted_calculation
|
31
|
+
count
|
32
|
+
end
|
21
33
|
end
|
22
34
|
|
23
35
|
class Post < ActiveRecord::Base
|
@@ -93,6 +105,8 @@ module TestDatabase
|
|
93
105
|
end
|
94
106
|
|
95
107
|
def test_table_name
|
108
|
+
# This test is to ensure there's not an error when using the table
|
109
|
+
# name as part of the column name.
|
96
110
|
assert_empty User.group_by_day("users.created_at").count
|
97
111
|
end
|
98
112
|
|
@@ -192,7 +206,7 @@ module TestDatabase
|
|
192
206
|
assert_raises(NoMethodError) { User.group_by_day(:created_at).no_such_method }
|
193
207
|
end
|
194
208
|
|
195
|
-
def
|
209
|
+
def test_respond_to_order
|
196
210
|
assert User.group_by_day(:created_at).respond_to?(:order)
|
197
211
|
end
|
198
212
|
|
@@ -333,17 +347,40 @@ module TestDatabase
|
|
333
347
|
assert_equal 2, User.group_by_day(:created_at, carry_forward: true).count[Date.parse("2014-05-02")]
|
334
348
|
end
|
335
349
|
|
336
|
-
#
|
337
|
-
|
338
|
-
def test_dates
|
339
|
-
create_user "2014-03-01 12:00:00 UTC"
|
340
|
-
assert_equal ({Date.parse("2014-03-01") => 1}), User.group_by_day(:created_at, dates: true).count
|
341
|
-
end
|
350
|
+
# no column
|
342
351
|
|
343
352
|
def test_no_column
|
344
353
|
assert_raises(ArgumentError) { User.group_by_day.first }
|
345
354
|
end
|
346
355
|
|
356
|
+
# custom model calculation methods
|
357
|
+
|
358
|
+
def test_custom_model_calculation_method
|
359
|
+
create_user "2014-05-01"
|
360
|
+
create_user "2014-05-01"
|
361
|
+
create_user "2014-05-03"
|
362
|
+
|
363
|
+
expected = {
|
364
|
+
Date.parse("2014-05-01") => 2,
|
365
|
+
Date.parse("2014-05-02") => 0,
|
366
|
+
Date.parse("2014-05-03") => 1
|
367
|
+
}
|
368
|
+
|
369
|
+
assert_equal expected, User.group_by_day(:created_at).custom_count
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_using_unlisted_calculation_method_returns_new_series_instance
|
373
|
+
assert_instance_of Groupdate::Series, User.group_by_day(:created_at).unlisted_calculation
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_using_listed_but_undefined_custom_calculation_method_raises_error
|
377
|
+
assert_raises(RuntimeError) do
|
378
|
+
User.group_by_day(:created_at).undefined_calculation
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
private
|
383
|
+
|
347
384
|
def call_method(method, field, options)
|
348
385
|
User.group_by_period(method, field, options).count
|
349
386
|
end
|
@@ -1005,16 +1042,51 @@ module TestGroupdate
|
|
1005
1042
|
expected = {
|
1006
1043
|
Date.parse("2013-05-03") => 1
|
1007
1044
|
}
|
1008
|
-
assert_equal expected, result(:day, "2013-05-03", false
|
1045
|
+
assert_equal expected, result(:day, "2013-05-03", false)
|
1009
1046
|
end
|
1010
1047
|
|
1011
1048
|
def test_date_column_with_time_zone
|
1012
1049
|
# TODO change for Groupdate 3.0
|
1013
|
-
|
1050
|
+
expected = {
|
1051
|
+
Date.parse("2013-05-02") => 1
|
1052
|
+
}
|
1053
|
+
assert_equal expected, result(:day, "2013-05-03", true)
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
def test_date_column_with_time_zone_false
|
1057
|
+
Time.zone = pt
|
1058
|
+
create_user "2013-05-03"
|
1014
1059
|
expected = {
|
1015
1060
|
Date.parse("2013-05-03") => 1
|
1016
1061
|
}
|
1017
|
-
assert_equal expected,
|
1062
|
+
assert_equal expected, call_method(:day, :created_at, time_zone: false)
|
1063
|
+
ensure
|
1064
|
+
Time.zone = nil
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
# date range
|
1068
|
+
|
1069
|
+
def test_date_range
|
1070
|
+
ENV["TZ"] = "Europe/Oslo"
|
1071
|
+
expected = {
|
1072
|
+
Date.parse("2013-05-01") => 0,
|
1073
|
+
Date.parse("2013-05-02") => 0,
|
1074
|
+
Date.parse("2013-05-03") => 0
|
1075
|
+
}
|
1076
|
+
assert_equal expected, call_method(:day, :created_at, series: true, range: Date.parse("2013-05-01")..Date.parse("2013-05-03"))
|
1077
|
+
ensure
|
1078
|
+
ENV["TZ"] = "UTC"
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
def test_date_range_exclude_end
|
1082
|
+
ENV["TZ"] = "Europe/Oslo"
|
1083
|
+
expected = {
|
1084
|
+
Date.parse("2013-05-01") => 0,
|
1085
|
+
Date.parse("2013-05-02") => 0
|
1086
|
+
}
|
1087
|
+
assert_equal expected, call_method(:day, :created_at, series: true, range: Date.parse("2013-05-01")...Date.parse("2013-05-03"))
|
1088
|
+
ensure
|
1089
|
+
ENV["TZ"] = "UTC"
|
1018
1090
|
end
|
1019
1091
|
|
1020
1092
|
# day start
|
@@ -1027,6 +1099,8 @@ module TestGroupdate
|
|
1027
1099
|
assert_result_date :day, "2013-05-03", "2013-05-03 02:30:00", false, day_start: 2.5
|
1028
1100
|
end
|
1029
1101
|
|
1102
|
+
private
|
1103
|
+
|
1030
1104
|
# helpers
|
1031
1105
|
|
1032
1106
|
def assert_format(method, expected, format, options = {})
|
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: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- groupdate.gemspec
|
126
126
|
- lib/groupdate.rb
|
127
127
|
- lib/groupdate/active_record.rb
|
128
|
+
- lib/groupdate/calculations.rb
|
128
129
|
- lib/groupdate/enumerable.rb
|
129
130
|
- lib/groupdate/magic.rb
|
130
131
|
- lib/groupdate/order_hack.rb
|
@@ -162,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
163
|
version: '0'
|
163
164
|
requirements: []
|
164
165
|
rubyforge_project:
|
165
|
-
rubygems_version: 2.
|
166
|
+
rubygems_version: 2.5.1
|
166
167
|
signing_key:
|
167
168
|
specification_version: 4
|
168
169
|
summary: The simplest way to group temporal data
|
@@ -178,4 +179,3 @@ test_files:
|
|
178
179
|
- test/postgresql_test.rb
|
179
180
|
- test/redshift_test.rb
|
180
181
|
- test/test_helper.rb
|
181
|
-
has_rdoc:
|