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 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: