groupdate 3.0.2 → 3.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8a15c2188ffbf51536333cfad342a88325d5866c
4
- data.tar.gz: 962f3ddeffa87168994308c6740ad126393db9e3
3
+ metadata.gz: 87e6343538ca0aa70041863153b514d765952ca9
4
+ data.tar.gz: a5121f5bab5c8f9de575e5adcf09885c88abd08a
5
5
  SHA512:
6
- metadata.gz: caf2a8b62b7d05e4934f3035b1d7e16c739bef41d316ced765ceb48b0b5c36cb29bad12579ca90b3cfdacdb870d4ab721bc0d925aa5d1c791b15a393a067d4ba
7
- data.tar.gz: dabd8ea049f07f730c219348dc247996838831221252eecb3a58a40fd650aa6a16b552a707db4aba1e6b522e984300888e4a7615fb8737bb0360ae2f2ff8e73b
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
@@ -1,3 +1,8 @@
1
+ ## 3.1.0
2
+
3
+ - Better support for date columns with `time_zone: false`
4
+ - Better date range handling for `range` option
5
+
1
6
  ## 3.0.2
2
7
 
3
8
  - Fixed `group_by_period` with associations
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
@@ -1,6 +1,7 @@
1
1
  require "active_record"
2
2
  require "groupdate/order_hack"
3
3
  require "groupdate/scopes"
4
+ require "groupdate/calculations"
4
5
  require "groupdate/series"
5
6
 
6
7
  ActiveRecord::Base.send(:extend, Groupdate::Scopes)
@@ -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
@@ -158,7 +158,8 @@ module Groupdate
158
158
 
159
159
  def time_zone
160
160
  @time_zone ||= begin
161
- time_zone = options[:time_zone] || Groupdate.time_zone || Time.zone || "Etc/UTC"
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 !time_range && options[:last]
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
@@ -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
- # https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb
13
- if ActiveRecord::Calculations.method_defined?(method)
13
+ if @calculations.include?(method)
14
14
  magic.perform(relation, method, *args, &block)
15
- elsif @relation.respond_to?(method, true)
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
- ActiveRecord::Calculations.method_defined?(method) || relation.respond_to?(method) || super
23
+ @calculations.include?(method) || relation.respond_to?(method) || super
24
24
  end
25
25
 
26
26
  def reverse_order_value
@@ -1,3 +1,3 @@
1
1
  module Groupdate
2
- VERSION = "3.0.2"
2
+ VERSION = "3.1.0"
3
3
  end
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 test_respond_to_where
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
- # dates
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, dates: true)
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
- skip
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, result(:day, "2013-05-03", true, dates: true)
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.2
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-08-10 00:00:00.000000000 Z
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.6.1
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: