groupdate 1.0.0 → 1.0.1

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: 0f28f0b992e2888b1f1adcf75bf3170f6e3d8fb6
4
- data.tar.gz: c0184bc2c7cb5362559856fc897f5f215a2bab35
3
+ metadata.gz: 9f1468425ce9451398c5c487174224dc971a30d2
4
+ data.tar.gz: 5fff75e9b44d6651ca75d634f3bff1ceb68901de
5
5
  SHA512:
6
- metadata.gz: 657151e8e0ebdc8d823af7c0d0116691d846f4347d52b22bf7951b1cdd89e65f50435ff70a19fc30b093c6c28e7c11fa49880c208b9afa0f3fac340aa4cc2a35
7
- data.tar.gz: 7bb1f7899d84420aea67ebf935a5d6029985a9953fed4b7343cbe410fdc43aef0961118cd103c8966796c0b19008a0e87d5d59b61d52df18bb93b4fb94bb0f7f
6
+ metadata.gz: c14ee2daf271500e82db8e221fb8e1dcee97694355e244664c575b9e035c03fd62ba5e4a09189b4555b76f4b685ea9261e58a7101d707b892e2e8e52a051abb1
7
+ data.tar.gz: 33c9afbdc4ec5bf3e99329c99c6b41702507762f122acbae0addbac7faeda9c6e87aa147b4f3c53cefceb9b58bb7643d21674958815cdb3974dfaa4df920c36b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.0.1
2
+
3
+ - Fixed series for Rails < 3.2 and MySQL 2
4
+
1
5
  ## 1.0.0
2
6
 
3
7
  - First major release
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  # gem "activerecord", github: "rails/rails"
7
+ # gem "activerecord", "3.0.20"
8
+ # gem "mysql2", "< 0.3.0"
7
9
 
8
10
  platform :jruby do
9
11
  gem "activerecord-jdbcpostgresql-adapter", :github => "jruby/activerecord-jdbc-adapter"
data/Rakefile CHANGED
@@ -1,9 +1,19 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
+ task :default => :test
4
5
  Rake::TestTask.new do |t|
5
- t.libs = ["lib"]
6
- t.warning = false
7
- t.verbose = false
8
- t.test_files = FileList["test/*_test.rb"]
6
+ t.libs << "test"
7
+ t.pattern = "test/**/*_test.rb"
8
+ end
9
+
10
+ namespace :test do
11
+ Rake::TestTask.new(:postgresql) do |t|
12
+ t.libs << "test"
13
+ t.pattern = "test/postgresql_test.rb"
14
+ end
15
+ Rake::TestTask.new(:mysql) do |t|
16
+ t.libs << "test"
17
+ t.pattern = "test/mysql_test.rb"
18
+ end
9
19
  end
@@ -75,9 +75,9 @@ module Groupdate
75
75
  when "PostgreSQL"
76
76
  case field
77
77
  when "day_of_week"
78
- ["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ?)", time_zone]
78
+ ["EXTRACT(DOW from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
79
79
  when "hour_of_day"
80
- ["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)", time_zone]
80
+ ["EXTRACT(HOUR from #{column}::timestamptz AT TIME ZONE ?)::integer", time_zone]
81
81
  when "week" # start on Sunday, not PostgreSQL default Monday
82
82
  ["(DATE_TRUNC('#{field}', (#{column}::timestamptz + INTERVAL '1 day') AT TIME ZONE ?) - INTERVAL '1 day') AT TIME ZONE ?", time_zone, time_zone]
83
83
  else
@@ -12,12 +12,14 @@ module Groupdate
12
12
  end
13
13
 
14
14
  def build_series(count)
15
+ utc = ActiveSupport::TimeZone["UTC"]
16
+
15
17
  cast_method =
16
18
  case @field
17
19
  when "day_of_week", "hour_of_day"
18
20
  lambda{|k| k.to_i }
19
21
  else
20
- lambda{|k| k.is_a?(Time) ? k : Time.parse(k) }
22
+ lambda{|k| (k.is_a?(Time) ? k : utc.parse(k)).utc }
21
23
  end
22
24
 
23
25
  count = Hash[count.map do |k, v|
@@ -53,7 +55,8 @@ module Groupdate
53
55
  when "day"
54
56
  time.beginning_of_day
55
57
  when "week"
56
- time.beginning_of_week(:sunday)
58
+ # beginning_of_week does not support :sunday argument in activesupport < 3.2
59
+ (time - time.wday.days).midnight
57
60
  when "month"
58
61
  time.beginning_of_month
59
62
  else # year
@@ -68,7 +71,7 @@ module Groupdate
68
71
  series << series.last + step
69
72
  end
70
73
 
71
- series.map{|s| s.to_time }
74
+ series.map{|s| s.to_time.utc }
72
75
  end
73
76
 
74
77
  Hash[series.map do |k|
@@ -1,3 +1,3 @@
1
1
  module Groupdate
2
- VERSION = "1.0.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -0,0 +1,22 @@
1
+ require "test_helper"
2
+
3
+ class TestMysql < Minitest::Test
4
+ include TestGroupdate
5
+
6
+ def setup
7
+ User.establish_connection :adapter => "mysql2", :database => "groupdate_test", :username => "root"
8
+ end
9
+
10
+ def time_key(key)
11
+ if RUBY_PLATFORM == "java"
12
+ key.utc.strftime("%Y-%m-%d %H:%M:%S").gsub(/ 00\:00\:00\z/, "")
13
+ else
14
+ key
15
+ end
16
+ end
17
+
18
+ def number_key(key)
19
+ key
20
+ end
21
+
22
+ end
@@ -0,0 +1,30 @@
1
+ require "test_helper"
2
+
3
+ class TestPostgresql < Minitest::Test
4
+ include TestGroupdate
5
+
6
+ def setup
7
+ User.establish_connection :adapter => "postgresql", :database => "groupdate_test"
8
+ end
9
+
10
+ def time_key(key)
11
+ if RUBY_PLATFORM == "java"
12
+ key.utc.strftime("%Y-%m-%d %H:%M:%S%z")[0..-3]
13
+ else
14
+ if ActiveRecord::VERSION::MAJOR == 3
15
+ key.utc.strftime("%Y-%m-%d %H:%M:%S+00")
16
+ else
17
+ key
18
+ end
19
+ end
20
+ end
21
+
22
+ def number_key(key)
23
+ if RUBY_PLATFORM != "java" and ActiveRecord::VERSION::MAJOR == 3
24
+ key.to_s
25
+ else
26
+ key
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,306 @@
1
+ require "bundler/setup"
2
+ Bundler.require(:default)
3
+ require "minitest/autorun"
4
+ require "minitest/pride"
5
+ require "logger"
6
+
7
+ # for debugging
8
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
9
+
10
+ # rails does this in activerecord/lib/active_record/railtie.rb
11
+ ActiveRecord::Base.default_timezone = :utc
12
+ ActiveRecord::Base.time_zone_aware_attributes = true
13
+
14
+ class User < ActiveRecord::Base
15
+ end
16
+
17
+ # migrations
18
+ %w(postgresql mysql2).each do |adapter|
19
+ ActiveRecord::Base.establish_connection :adapter => adapter, :database => "groupdate_test", :username => adapter == "mysql2" ? "root" : nil
20
+
21
+ unless ActiveRecord::Base.connection.table_exists? "users"
22
+ ActiveRecord::Migration.create_table :users do |t|
23
+ t.string :name
24
+ t.integer :score
25
+ t.timestamps
26
+ end
27
+ end
28
+ end
29
+
30
+ module TestGroupdate
31
+
32
+ # second
33
+
34
+ def test_second_end_of_second
35
+ assert_result_time :second, "2013-05-03 00:00:00 UTC", "2013-05-03 00:00:00.999"
36
+ end
37
+
38
+ def test_second_start_of_second
39
+ assert_result_time :second, "2013-05-03 00:00:01 UTC", "2013-05-03 00:00:01.000"
40
+ end
41
+
42
+ # minute
43
+
44
+ def test_minute_end_of_minute
45
+ assert_result_time :minute, "2013-05-03 00:00:00 UTC", "2013-05-03 00:00:59"
46
+ end
47
+
48
+ def test_minute_start_of_minute
49
+ assert_result_time :minute, "2013-05-03 00:01:00 UTC", "2013-05-03 00:01:00"
50
+ end
51
+
52
+ # hour
53
+
54
+ def test_hour_end_of_hour
55
+ assert_result_time :hour, "2013-05-03 00:00:00 UTC", "2013-05-03 00:59:59"
56
+ end
57
+
58
+ def test_hour_start_of_hour
59
+ assert_result_time :hour, "2013-05-03 01:00:00 UTC", "2013-05-03 01:00:00"
60
+ end
61
+
62
+ # day
63
+
64
+ def test_day_end_of_day
65
+ assert_result_time :day, "2013-05-03 00:00:00 UTC", "2013-05-03 23:59:59"
66
+ end
67
+
68
+ def test_day_start_of_day
69
+ assert_result_time :day, "2013-05-04 00:00:00 UTC", "2013-05-04 00:00:00"
70
+ end
71
+
72
+ def test_day_end_of_day_with_time_zone
73
+ assert_result_time :day, "2013-05-02 00:00:00 PDT", "2013-05-03 06:59:59", true
74
+ end
75
+
76
+ def test_day_start_of_day_with_time_zone
77
+ assert_result_time :day, "2013-05-03 00:00:00 PDT", "2013-05-03 07:00:00", true
78
+ end
79
+
80
+ # week
81
+
82
+ def test_week_end_of_week
83
+ assert_result_time :week, "2013-03-17 00:00:00 UTC", "2013-03-23 23:59:59"
84
+ end
85
+
86
+ def test_week_start_of_week
87
+ assert_result_time :week, "2013-03-24 00:00:00 UTC", "2013-03-24 00:00:00"
88
+ end
89
+
90
+ def test_week_end_of_week_with_time_zone
91
+ assert_result_time :week, "2013-03-10 00:00:00 PST", "2013-03-17 06:59:59", true
92
+ end
93
+
94
+ def test_week_start_of_week_with_time_zone
95
+ assert_result_time :week, "2013-03-17 00:00:00 PDT", "2013-03-17 07:00:00", true
96
+ end
97
+
98
+ # month
99
+
100
+ def test_month_end_of_month
101
+ assert_result_time :month, "2013-05-01 00:00:00 UTC", "2013-05-31 23:59:59"
102
+ end
103
+
104
+ def test_month_start_of_month
105
+ assert_result_time :month, "2013-06-01 00:00:00 UTC", "2013-06-01 00:00:00"
106
+ end
107
+
108
+ def test_month_end_of_month_with_time_zone
109
+ assert_result_time :month, "2013-05-01 00:00:00 PDT", "2013-06-01 06:59:59", true
110
+ end
111
+
112
+ def test_month_start_of_month_with_time_zone
113
+ assert_result_time :month, "2013-06-01 00:00:00 PDT", "2013-06-01 07:00:00", true
114
+ end
115
+
116
+ # year
117
+
118
+ def test_year_end_of_year
119
+ assert_result_time :year, "2013-01-01 00:00:00 UTC", "2013-12-31 23:59:59"
120
+ end
121
+
122
+ def test_year_start_of_year
123
+ assert_result_time :year, "2014-01-01 00:00:00 UTC", "2014-01-01 00:00:00"
124
+ end
125
+
126
+ def test_year_end_of_year_with_time_zone
127
+ assert_result_time :year, "2013-01-01 00:00:00 PST", "2014-01-01 07:59:59", true
128
+ end
129
+
130
+ def test_year_start_of_year_with_time_zone
131
+ assert_result_time :year, "2014-01-01 00:00:00 PST", "2014-01-01 08:00:00", true
132
+ end
133
+
134
+ # hour of day
135
+
136
+ def test_hour_of_day_end_of_hour
137
+ assert_result :hour_of_day, 0, "2013-01-01 00:59:59"
138
+ end
139
+
140
+ def test_hour_of_day_start_of_hour
141
+ assert_result :hour_of_day, 1, "2013-01-01 01:00:00"
142
+ end
143
+
144
+ def test_hour_of_day_end_of_hour_with_time_zone
145
+ assert_result :hour_of_day, 0, "2013-01-01 08:59:59", true
146
+ end
147
+
148
+ def test_hour_of_day_start_of_hour_with_time_zone
149
+ assert_result :hour_of_day, 1, "2013-01-01 09:00:00", true
150
+ end
151
+
152
+ # day of week
153
+
154
+ def test_day_of_week_end_of_day
155
+ assert_result :day_of_week, 2, "2013-01-01 23:59:59"
156
+ end
157
+
158
+ def test_day_of_week_start_of_day
159
+ assert_result :day_of_week, 3, "2013-01-02 00:00:00"
160
+ end
161
+
162
+ def test_day_of_week_end_of_week_with_time_zone
163
+ assert_result :day_of_week, 2, "2013-01-02 07:59:59", true
164
+ end
165
+
166
+ def test_day_of_week_start_of_week_with_time_zone
167
+ assert_result :day_of_week, 3, "2013-01-02 08:00:00", true
168
+ end
169
+
170
+ # zeros
171
+
172
+ def test_zeros_second
173
+ assert_zeros :second, "2013-05-01 00:00:01 UTC", ["2013-05-01 00:00:00 UTC", "2013-05-01 00:00:01 UTC", "2013-05-01 00:00:02 UTC"], "2013-05-01 00:00:00.999 UTC", "2013-05-01 00:00:02 UTC"
174
+ end
175
+
176
+ def test_zeros_minute
177
+ assert_zeros :minute, "2013-05-01 00:01:00 UTC", ["2013-05-01 00:00:00 UTC", "2013-05-01 00:01:00 UTC", "2013-05-01 00:02:00 UTC"], "2013-05-01 00:00:59 UTC", "2013-05-01 00:02:00 UTC"
178
+ end
179
+
180
+ def test_zeros_hour
181
+ assert_zeros :hour, "2013-05-01 04:01:01 UTC", ["2013-05-01 03:00:00 UTC", "2013-05-01 04:00:00 UTC", "2013-05-01 05:00:00 UTC"], "2013-05-01 03:59:59 UTC", "2013-05-01 05:00:00 UTC"
182
+ end
183
+
184
+ def test_zeros_day
185
+ assert_zeros :day, "2013-05-01 20:00:00 UTC", ["2013-04-30 00:00:00 UTC", "2013-05-01 00:00:00 UTC", "2013-05-02 00:00:00 UTC"], "2013-04-30 00:00:00 UTC", "2013-05-02 23:59:59 UTC"
186
+ end
187
+
188
+ def test_zeros_day_time_zone
189
+ assert_zeros :day, "2013-05-01 20:00:00 PDT", ["2013-04-30 00:00:00 PDT", "2013-05-01 00:00:00 PDT", "2013-05-02 00:00:00 PDT"], "2013-04-30 00:00:00 PDT", "2013-05-02 23:59:59 PDT", true
190
+ end
191
+
192
+ def test_zeros_week
193
+ assert_zeros :week, "2013-05-01 20:00:00 UTC", ["2013-04-21 00:00:00 UTC", "2013-04-28 00:00:00 UTC", "2013-05-05 00:00:00 UTC"], "2013-04-27 23:59:59 UTC", "2013-05-11 23:59:59 UTC"
194
+ end
195
+
196
+ def test_zeros_week_time_zone
197
+ assert_zeros :week, "2013-05-01 20:00:00 PDT", ["2013-04-21 00:00:00 PDT", "2013-04-28 00:00:00 PDT", "2013-05-05 00:00:00 PDT"], "2013-04-27 23:59:59 PDT", "2013-05-11 23:59:59 PDT", true
198
+ end
199
+
200
+ def test_zeros_month
201
+ assert_zeros :month, "2013-04-16 20:00:00 UTC", ["2013-03-01 00:00:00 UTC", "2013-04-01 00:00:00 UTC", "2013-05-01 00:00:00 UTC"], "2013-03-01 00:00:00 UTC", "2013-05-31 23:59:59 UTC"
202
+ end
203
+
204
+ def test_zeros_month_time_zone
205
+ 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
206
+ end
207
+
208
+ def test_zeros_year
209
+ 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"
210
+ end
211
+
212
+ def test_zeros_year_time_zone
213
+ assert_zeros :year, "2013-04-16 20:00:00 PDT", ["2012-01-01 00:00:00 PST", "2013-01-01 00:00:00 PST", "2014-01-01 00:00:00 PST"], "2012-01-01 00:00:00 PST", "2014-12-31 23:59:59 PST", true
214
+ end
215
+
216
+ def test_zeros_day_of_week
217
+ create_user "2013-05-01 00:00:00 UTC"
218
+ expected = {}
219
+ 7.times do |n|
220
+ expected[n] = n == 3 ? 1 : 0
221
+ end
222
+ assert_equal(expected, User.group_by_day_of_week(:created_at, Time.zone, true).count(:created_at))
223
+ end
224
+
225
+ def test_zeros_hour_of_day
226
+ create_user "2013-05-01 20:00:00 UTC"
227
+ expected = {}
228
+ 24.times do |n|
229
+ expected[n] = n == 20 ? 1 : 0
230
+ end
231
+ assert_equal(expected, User.group_by_hour_of_day(:created_at, Time.zone, true).count(:created_at))
232
+ end
233
+
234
+ def test_zeros_excludes_end
235
+ create_user "2013-05-02 00:00:00 UTC"
236
+ expected = {
237
+ Time.parse("2013-05-01 00:00:00 UTC") => 0
238
+ }
239
+ assert_equal(expected, User.group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")...Time.parse("2013-05-02 00:00:00 UTC")).count)
240
+ end
241
+
242
+ def test_zeros_previous_scope
243
+ create_user "2013-05-01 00:00:00 UTC"
244
+ expected = {
245
+ Time.parse("2013-05-01 00:00:00 UTC") => 0
246
+ }
247
+ assert_equal(expected, User.where("id = 0").group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")..Time.parse("2013-05-01 23:59:59 UTC")).count)
248
+ end
249
+
250
+ # misc
251
+
252
+ def test_order_day
253
+ assert_equal({}, User.group_by_day(:created_at).order("day desc").limit(20).count)
254
+ end
255
+
256
+ def test_order_week
257
+ assert_equal({}, User.group_by_week(:created_at).order("week asc").count)
258
+ end
259
+
260
+ def test_order_hour_of_day
261
+ assert_equal({}, User.group_by_hour_of_day(:created_at).order("hour_of_day desc").count)
262
+ end
263
+
264
+ def test_table_name
265
+ assert_equal({}, User.group_by_day("users.created_at").count)
266
+ end
267
+
268
+ def test_previous_scopes
269
+ create_user "2013-05-01 00:00:00 UTC"
270
+ assert_equal({}, User.where("id = 0").group_by_day(:created_at).count)
271
+ end
272
+
273
+ # helpers
274
+
275
+ def assert_result_time(method, expected, time_str, time_zone = false)
276
+ assert_result method, Time.parse(expected), time_str, time_zone
277
+ end
278
+
279
+ def assert_result(method, expected, time_str, time_zone = false)
280
+ create_user time_str
281
+ expected = expected.is_a?(Time) ? time_key(expected) : number_key(expected)
282
+ assert_equal(ordered_hash({expected => 1}), User.send(:"group_by_#{method}", :created_at, time_zone ? "Pacific Time (US & Canada)" : nil).order(method.to_s).count)
283
+ end
284
+
285
+ def assert_zeros(method, created_at, keys, range_start, range_end, time_zone = nil)
286
+ create_user created_at
287
+ expected = {}
288
+ keys.each_with_index do |key, i|
289
+ expected[Time.parse(key)] = i == 1 ? 1 : 0
290
+ end
291
+ assert_equal(expected, User.send(:"group_by_#{method}", :created_at, time_zone ? "Pacific Time (US & Canada)" : nil, Time.parse(range_start)..Time.parse(range_end)).count)
292
+ end
293
+
294
+ def ordered_hash(hash)
295
+ RUBY_VERSION =~ /1\.8/ ? hash.inject(ActiveSupport::OrderedHash.new){|h, (k, v)| h[k] = v; h } : hash
296
+ end
297
+
298
+ def create_user(created_at)
299
+ User.create!(:name => "Andrew", :score => 1, :created_at => ActiveSupport::TimeZone["UTC"].parse(created_at))
300
+ end
301
+
302
+ def teardown
303
+ User.delete_all
304
+ end
305
+
306
+ end
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: 1.0.0
4
+ version: 1.0.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: 2013-05-16 00:00:00.000000000 Z
11
+ date: 2013-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -114,7 +114,9 @@ files:
114
114
  - lib/groupdate/scopes.rb
115
115
  - lib/groupdate/series.rb
116
116
  - lib/groupdate/version.rb
117
- - test/groupdate_test.rb
117
+ - test/mysql_test.rb
118
+ - test/postgresql_test.rb
119
+ - test/test_helper.rb
118
120
  homepage: ''
119
121
  licenses:
120
122
  - MIT
@@ -140,4 +142,6 @@ signing_key:
140
142
  specification_version: 4
141
143
  summary: The simplest way to group temporal data
142
144
  test_files:
143
- - test/groupdate_test.rb
145
+ - test/mysql_test.rb
146
+ - test/postgresql_test.rb
147
+ - test/test_helper.rb
@@ -1,288 +0,0 @@
1
- require "bundler/setup"
2
- Bundler.require(:default)
3
- require "minitest/autorun"
4
- require "minitest/pride"
5
- require "logger"
6
-
7
- # for debugging
8
- # ActiveRecord::Base.logger = Logger.new(STDOUT)
9
-
10
- # rails does this in activerecord/lib/active_record/railtie.rb
11
- ActiveRecord::Base.default_timezone = :utc
12
- ActiveRecord::Base.time_zone_aware_attributes = true
13
-
14
- class User < ActiveRecord::Base
15
- end
16
-
17
- # migrations
18
- %w(postgresql mysql2).each do |adapter|
19
- ActiveRecord::Base.establish_connection :adapter => adapter, :database => "groupdate_test", :username => adapter == "mysql2" ? "root" : nil
20
-
21
- unless ActiveRecord::Base.connection.table_exists? "users"
22
- ActiveRecord::Migration.create_table :users do |t|
23
- t.string :name
24
- t.integer :score
25
- t.timestamps
26
- end
27
- end
28
- end
29
-
30
- describe Groupdate do
31
- %w(postgresql mysql2).each do |adapter|
32
- describe adapter do
33
-
34
- before do
35
- User.establish_connection :adapter => adapter, :database => "groupdate_test", :username => adapter == "mysql2" ? "root" : nil
36
- User.delete_all
37
- end
38
-
39
- it "works!" do
40
- [
41
- {:name => "Andrew", :score => 1, :created_at => Time.parse("2013-04-01 00:00:00 UTC")},
42
- {:name => "Jordan", :score => 2, :created_at => Time.parse("2013-04-01 00:00:00 UTC")},
43
- {:name => "Nick", :score => 3, :created_at => Time.parse("2013-04-02 00:00:00 UTC")}
44
- ].each{|u| User.create!(u) }
45
-
46
- assert_equal(
47
- ordered_hash({
48
- time_key("2013-04-01 00:00:00 UTC") => 1,
49
- time_key("2013-04-02 00:00:00 UTC") => 1
50
- }),
51
- User.where("score > 1").group_by_day(:created_at).count
52
- )
53
- end
54
-
55
- it "doesn't throw exception with order" do
56
- assert_equal({}, User.group_by_day(:created_at).order("day desc").limit(20).count)
57
- assert_equal({}, User.group_by_week(:created_at).order("week asc").count)
58
- assert_equal({}, User.group_by_hour_of_day(:created_at).order("hour_of_day desc").count)
59
- end
60
-
61
- it "allows for table name" do
62
- assert_equal({}, User.group_by_day("users.created_at").count)
63
- end
64
-
65
- it "group_by_second" do
66
- assert_group :second, "2013-04-01 00:00:01 UTC", "2013-04-01 00:00:01 UTC"
67
- end
68
-
69
- it "group_by_minute" do
70
- assert_group :minute, "2013-04-01 00:01:01 UTC", "2013-04-01 00:01:00 UTC"
71
- end
72
-
73
- it "group_by_hour" do
74
- assert_group :hour, "2013-04-01 01:01:01 UTC", "2013-04-01 01:00:00 UTC"
75
- end
76
-
77
- it "group_by_day" do
78
- assert_group :day, "2013-04-01 01:01:01 UTC", "2013-04-01 00:00:00 UTC"
79
- end
80
-
81
- it "group_by_day with time zone" do
82
- assert_group_tz :day, "2013-04-01 01:01:01 UTC", "2013-03-31 07:00:00 UTC"
83
- end
84
-
85
- it "group_by_week" do
86
- assert_group :week, "2013-03-17 01:01:01 UTC", "2013-03-17 00:00:00 UTC"
87
- end
88
-
89
- it "group_by_week with time zone" do # day of DST
90
- assert_group_tz :week, "2013-03-17 01:01:01 UTC", "2013-03-10 08:00:00 UTC"
91
- end
92
-
93
- it "group_by_month" do
94
- assert_group :month, "2013-04-01 01:01:01 UTC", "2013-04-01 00:00:00 UTC"
95
- end
96
-
97
- it "group_by_month with time zone" do
98
- assert_group_tz :month, "2013-04-01 01:01:01 UTC", "2013-03-01 08:00:00 UTC"
99
- end
100
-
101
- it "group_by_year" do
102
- assert_group :year, "2013-01-01 01:01:01 UTC", "2013-01-01 00:00:00 UTC"
103
- end
104
-
105
- it "group_by_year with time zone" do
106
- assert_group_tz :year, "2013-01-01 01:01:01 UTC", "2012-01-01 08:00:00 UTC"
107
- end
108
-
109
- it "group_by_hour_of_day" do
110
- assert_group_number :hour_of_day, "2013-01-01 11:00:00 UTC", 11
111
- end
112
-
113
- it "group_by_hour_of_day with time zone" do
114
- assert_group_number_tz :hour_of_day, "2013-01-01 11:00:00 UTC", 3
115
- end
116
-
117
- it "group_by_day_of_week" do
118
- assert_group_number :day_of_week, "2013-03-03 00:00:00 UTC", 0
119
- end
120
-
121
- it "group_by_day_of_week with time zone" do
122
- assert_group_number_tz :day_of_week, "2013-03-03 00:00:00 UTC", 6
123
- end
124
-
125
- it "works with previous scopes" do
126
- create_user "2013-05-01 00:00:00 UTC"
127
- assert_equal({}, User.where("id = 0").group_by_day(:created_at).count)
128
- end
129
-
130
- describe "returns zeros" do
131
-
132
- it "group_by_second" do
133
- assert_zeros :second, "2013-05-01 00:00:01 UTC", ["2013-05-01 00:00:00 UTC", "2013-05-01 00:00:01 UTC", "2013-05-01 00:00:02 UTC"], "2013-05-01 00:00:00.999 UTC", "2013-05-01 00:00:02 UTC"
134
- end
135
-
136
- it "group_by_minute" do
137
- assert_zeros :minute, "2013-05-01 00:01:00 UTC", ["2013-05-01 00:00:00 UTC", "2013-05-01 00:01:00 UTC", "2013-05-01 00:02:00 UTC"], "2013-05-01 00:00:59 UTC", "2013-05-01 00:02:00 UTC"
138
- end
139
-
140
- it "group_by_hour" do
141
- assert_zeros :hour, "2013-05-01 04:01:01 UTC", ["2013-05-01 03:00:00 UTC", "2013-05-01 04:00:00 UTC", "2013-05-01 05:00:00 UTC"], "2013-05-01 03:59:59 UTC", "2013-05-01 05:00:00 UTC"
142
- end
143
-
144
- it "group_by_day" do
145
- assert_zeros :day, "2013-05-01 20:00:00 UTC", ["2013-04-30 00:00:00 UTC", "2013-05-01 00:00:00 UTC", "2013-05-02 00:00:00 UTC"], "2013-04-30 00:00:00 UTC", "2013-05-02 23:59:59 UTC"
146
- end
147
-
148
- it "group_by_day with time zone" do
149
- assert_zeros_tz :day, "2013-05-01 20:00:00 PDT", ["2013-04-30 00:00:00 PDT", "2013-05-01 00:00:00 PDT", "2013-05-02 00:00:00 PDT"], "2013-04-30 00:00:00 PDT", "2013-05-02 23:59:59 PDT"
150
- end
151
-
152
- it "group_by_week" do
153
- assert_zeros :week, "2013-05-01 20:00:00 UTC", ["2013-04-21 00:00:00 UTC", "2013-04-28 00:00:00 UTC", "2013-05-05 00:00:00 UTC"], "2013-04-27 23:59:59 UTC", "2013-05-11 23:59:59 UTC"
154
- end
155
-
156
- it "group_by_week with time zone" do
157
- assert_zeros_tz :week, "2013-05-01 20:00:00 PDT", ["2013-04-21 00:00:00 PDT", "2013-04-28 00:00:00 PDT", "2013-05-05 00:00:00 PDT"], "2013-04-27 23:59:59 PDT", "2013-05-11 23:59:59 PDT"
158
- end
159
-
160
- it "group_by_month" do
161
- assert_zeros :month, "2013-04-16 20:00:00 UTC", ["2013-03-01 00:00:00 UTC", "2013-04-01 00:00:00 UTC", "2013-05-01 00:00:00 UTC"], "2013-03-01 00:00:00 UTC", "2013-05-31 23:59:59 UTC"
162
- end
163
-
164
- it "group_by_month with time zone" do
165
- assert_zeros_tz :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"
166
- end
167
-
168
- it "group_by_year" do
169
- 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"
170
- end
171
-
172
- it "group_by_year with time zone" do
173
- assert_zeros_tz :year, "2013-04-16 20:00:00 PDT", ["2012-01-01 00:00:00 PST", "2013-01-01 00:00:00 PST", "2014-01-01 00:00:00 PST"], "2012-01-01 00:00:00 PST", "2014-12-31 23:59:59 PST"
174
- end
175
-
176
- it "group_by_day_of_week" do
177
- create_user "2013-05-01 00:00:00 UTC"
178
- expected = {}
179
- 7.times do |n|
180
- expected[n] = n == 3 ? 1 : 0
181
- end
182
- assert_equal(expected, User.group_by_day_of_week(:created_at, Time.zone, true).count(:created_at))
183
- end
184
-
185
- it "group_by_hour_of_day" do
186
- create_user "2013-05-01 20:00:00 UTC"
187
- expected = {}
188
- 24.times do |n|
189
- expected[n] = n == 20 ? 1 : 0
190
- end
191
- assert_equal(expected, User.group_by_hour_of_day(:created_at, Time.zone, true).count(:created_at))
192
- end
193
-
194
- it "excludes end" do
195
- create_user "2013-05-02 00:00:00 UTC"
196
- expected = {
197
- Time.parse("2013-05-01 00:00:00 UTC") => 0
198
- }
199
- assert_equal(expected, User.group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")...Time.parse("2013-05-02 00:00:00 UTC")).count)
200
- end
201
-
202
- it "works with previous scopes" do
203
- create_user "2013-05-01 00:00:00 UTC"
204
- expected = {
205
- Time.parse("2013-05-01 00:00:00 UTC") => 0
206
- }
207
- assert_equal(expected, User.where("id = 0").group_by_day(:created_at, Time.zone, Time.parse("2013-05-01 00:00:00 UTC")..Time.parse("2013-05-01 23:59:59 UTC")).count)
208
- end
209
-
210
- end
211
-
212
- end
213
- end
214
-
215
- # helper methods
216
-
217
- def assert_group(method, created_at, key, time_zone = nil)
218
- create_user created_at
219
- assert_equal(ordered_hash({time_key(key) => 1}), User.send(:"group_by_#{method}", :created_at, time_zone).order(method.to_s).count)
220
- end
221
-
222
- def assert_group_tz(method, created_at, key)
223
- assert_group method, created_at, key, "Pacific Time (US & Canada)"
224
- end
225
-
226
- def assert_group_number(method, created_at, key, time_zone = nil)
227
- create_user created_at
228
- assert_equal(ordered_hash({number_key(key) => 1}), User.send(:"group_by_#{method}", :created_at, time_zone).order(method.to_s).count)
229
- end
230
-
231
- def assert_group_number_tz(method, created_at, key)
232
- assert_group_number method, created_at, key, "Pacific Time (US & Canada)"
233
- end
234
-
235
- def assert_zeros(method, created_at, keys, range_start, range_end, time_zone = nil, java_hack = false)
236
- create_user created_at
237
- expected = {}
238
- keys.each_with_index do |key, i|
239
- expected[Time.parse(key)] = i == 1 ? 1 : 0
240
- end
241
- assert_equal(expected, User.send(:"group_by_#{method}", :created_at, time_zone, Time.parse(range_start)..Time.parse(range_end)).count)
242
- end
243
-
244
- def assert_zeros_tz(method, created_at, keys, range_start, range_end)
245
- assert_zeros method, created_at, keys, range_start, range_end, "Pacific Time (US & Canada)", true
246
- end
247
-
248
- def time_key(key)
249
- if RUBY_PLATFORM == "java"
250
- if User.connection.adapter_name == "PostgreSQL"
251
- Time.parse(key).utc.strftime("%Y-%m-%d %H:%M:%S%z")[0..-3]
252
- else
253
- Time.parse(key).strftime("%Y-%m-%d %H:%M:%S").gsub(/ 00\:00\:00\z/, "")
254
- end
255
- else
256
- if User.connection.adapter_name == "PostgreSQL" and ActiveRecord::VERSION::MAJOR == 3
257
- Time.parse(key).utc.strftime("%Y-%m-%d %H:%M:%S+00")
258
- else
259
- Time.parse(key)
260
- end
261
- end
262
- end
263
-
264
- def number_key(key)
265
- if RUBY_PLATFORM == "java"
266
- if User.connection.adapter_name == "PostgreSQL"
267
- key.to_f
268
- else
269
- key
270
- end
271
- else
272
- if User.connection.adapter_name == "PostgreSQL"
273
- ActiveRecord::VERSION::MAJOR == 3 ? key.to_s : key.to_f
274
- else
275
- key
276
- end
277
- end
278
- end
279
-
280
- def ordered_hash(hash)
281
- RUBY_VERSION =~ /1\.8/ ? hash.inject(ActiveSupport::OrderedHash.new){|h, (k, v)| h[k] = v; h } : hash
282
- end
283
-
284
- def create_user(created_at)
285
- User.create!(:name => "Andrew", :score => 1, :created_at => Time.parse(created_at))
286
- end
287
-
288
- end