Commit 550f3fc2ff9b4e00204682d39412a5975e118691

Authored by Andrew Kane
1 parent b2363c28

Added tests

README.md
... ... @@ -16,13 +16,13 @@ PostgreSQL only at the moment - support for other datastores coming soon
16 16  
17 17 ```ruby
18 18 User.group_by_day(:created_at).count
19   -# => {2013-04-16 00:00:00 UTC=>50,2013-04-17 00:00:00 UTC=>100}
  19 +# => {"2013-04-16 00:00:00+00" => 50, "2013-04-17 00:00:00+00" => 100}
20 20  
21 21 Task.group_by_month(:updated_at).count
22   -# => {2013-04-01 00:00:00 UTC=>23,2013-04-01 00:00:00 UTC=>44}
  22 +# => {"2013-03-01 00:00:00+00" => 23, "2013-04-01 00:00:00+00" => 44}
23 23  
24 24 Goal.group_by_year(:accomplished_at).count
25   -# => {2012-01-01 00:00:00 UTC=>11,2013-01-01 00:00:00 UTC=>3}
  25 +# => {"2012-01-01 00:00:00+00" => 11, "2013-01-01 00:00:00+00" => 3}
26 26 ```
27 27  
28 28 The default time zone is `Time.zone`. Pass a time zone as the second argument.
... ... @@ -30,7 +30,7 @@ The default time zone is `Time.zone`. Pass a time zone as the second argument.
30 30 ```ruby
31 31 time_zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
32 32 User.group_by_week(:created_at, time_zone).count
33   -# => {2013-04-16 00:00:00 UTC=>80,2013-04-17 00:00:00 UTC=>70}
  33 +# => {"2013-04-16 07:00:00+00" => 80, "2013-04-17 07:00:00+00" => 70}
34 34 ```
35 35  
36 36 Use it with anything you can use `group` with:
... ... @@ -45,6 +45,8 @@ Go nuts!
45 45 Request.where(page: "/home").group_by_minute(:started_at).maximum(:request_time)
46 46 ```
47 47  
  48 +**Note:** On Rails 4 edge, queries return a Time object (much better!) as a result of [this commit](https://github.com/rails/rails/commit/2cc09441c2de57b024b11ba666ba1e72c2b20cfe)
  49 +
48 50 ## Installation
49 51  
50 52 Add this line to your application's Gemfile:
... ...
groupdate.gemspec
... ... @@ -22,4 +22,6 @@ Gem::Specification.new do |spec|
22 22  
23 23 spec.add_development_dependency "bundler", "~> 1.3"
24 24 spec.add_development_dependency "rake"
  25 + spec.add_development_dependency "minitest"
  26 + spec.add_development_dependency "pg"
25 27 end
... ...
lib/groupdate.rb
... ... @@ -29,9 +29,10 @@ module Groupdate
29 29 # http://www.postgresql.org/docs/9.1/static/functions-datetime.html
30 30 %w(microseconds milliseconds second minute hour day week month quarter year decade century millennium).each do |field|
31 31 self.scope :"group_by_#{field}", lambda {|column, time_zone = Time.zone|
32   - if time_zone.is_a?(ActiveSupport::TimeZone)
  32 + if defined?(ActiveSupport::TimeZone) and time_zone.is_a?(ActiveSupport::TimeZone)
33 33 time_zone = time_zone.tzinfo.name
34 34 end
  35 + time_zone ||= "Etc/UTC"
35 36 sql = "DATE_TRUNC('#{field}', #{column}::timestamptz AT TIME ZONE ?) AT TIME ZONE ?"
36 37 group(sanitize_sql_array([sql, time_zone, time_zone]))
37 38 }
... ...
test/groupdate_test.rb 0 → 100644
... ... @@ -0,0 +1,54 @@
  1 +require "minitest/autorun"
  2 +require "active_record"
  3 +require "groupdate"
  4 +require "logger"
  5 +
  6 +# for debugging
  7 +# ActiveRecord::Base.logger = Logger.new(STDOUT)
  8 +
  9 +# rails does this in activerecord/lib/active_record/railtie.rb
  10 +ActiveRecord::Base.default_timezone = :utc
  11 +ActiveRecord::Base.time_zone_aware_attributes = true
  12 +
  13 +# start connection
  14 +ActiveRecord::Base.establish_connection adapter: "postgresql", database: "groupdate"
  15 +
  16 +# ActiveRecord::Migration.create_table :users do |t|
  17 +# t.string :name
  18 +# t.integer :score
  19 +# t.timestamps
  20 +# end
  21 +
  22 +class User < ActiveRecord::Base
  23 +end
  24 +
  25 +class TestGroupdate < MiniTest::Unit::TestCase
  26 + def setup
  27 + User.delete_all
  28 + [
  29 + {name: "Andrew", score: 1, created_at: Time.parse("2013-04-01 00:00:00 UTC")},
  30 + {name: "Jordan", score: 2, created_at: Time.parse("2013-04-01 00:00:00 UTC")},
  31 + {name: "Nick", score: 3, created_at: Time.parse("2013-04-02 00:00:00 UTC")}
  32 + ].each{|u| User.create!(u) }
  33 + end
  34 +
  35 + def test_count
  36 + expected = {
  37 + "2013-04-01 00:00:00+00" => 2,
  38 + "2013-04-02 00:00:00+00" => 1
  39 + }
  40 + assert_equal expected, User.group_by_day(:created_at).count
  41 + end
  42 +
  43 + def test_time_zone
  44 + expected = {
  45 + "2013-03-31 07:00:00+00" => 2,
  46 + "2013-04-01 07:00:00+00" => 1
  47 + }
  48 + assert_equal expected, User.group_by_day(:created_at, "America/Los_Angeles").count
  49 + end
  50 +
  51 + def test_where
  52 + assert_equal({"2013-04-02 00:00:00+00" => 1}, User.where("score > 2").group_by_day(:created_at).count)
  53 + end
  54 +end
... ...