mongoid-metastamp 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) Peter Gumeson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,31 +1,157 @@
1
1
  Mongoid Metastamp
2
2
  =========================
3
3
 
4
- This gem provides Mongoid with enhanced meta-timestamps which allow querying by day, month, year, min, sec, or even by local vs. universal timezone.
4
+ Provides Mongoid with enhanced meta-timestamps that store additional parsed time metadata,
5
+ allowing more powerful querying on specific time fields and across normalized time zones.
6
+
5
7
 
6
8
  What It Does
7
9
  =========================
8
10
  (Or why would I want to use this?)
9
11
 
10
- Storing simple timestamps is all well and good if you only need to search inside a continuous range relative to one timezone.
11
- Sometimes however, you might want to search for all events that occurred between 9 AM and 5 PM, but across multiple locations and timezones.
12
+ Storing simple timestamps is all well and good if your queries are simple or involve just one timezone.
13
+ But sometimes you need to search across multiple locations while
14
+ ignoring timezone offsets. For example:
15
+
16
+ * Find all flights that depart from any airport between 1:00pm and 2:00pm local time.
17
+ * Return all employees that clocked in after 8:00am at either the Denver or San Diego location.
18
+
19
+ Other times you want to be able to query very specific parts of the
20
+ date/time that typically can't be accessed without parsing it:
21
+
22
+ * Find all transactions that occured on weekday afternoons in 2011.
23
+ * Return all users that signed up in January for the last 3 years.
24
+
25
+ Typically to do these things, you'd need to add a bunch of of complex time ranges to your query.
26
+ Or you might query the entire range and loop through each result, running additional tests on the parsed time.
27
+
28
+ Using mongoid-metastamp gives you a custom time field type that is normalized beforehand,
29
+ and then stored in a MongoDB friendly way for easy querying.
30
+
31
+
32
+ Installation
33
+ =========================
34
+
35
+ In your Gemfile
36
+
37
+ ```
38
+ gem 'mongoid-metastamp'
39
+ ```
40
+
41
+ ```
42
+ $ bundle install
43
+ ```
44
+
45
+ Usage
46
+ =========================
47
+
48
+ For the most part, `Mongoid::Metastamp::Time` fields can be used just like regular `Time` fields:
49
+
50
+ ```ruby
51
+ class MyEvent
52
+ include Mongoid::Document
53
+ field :starts_at, type: Mongoid::Metastamp::Time
54
+ field :ends_at, type: Mongoid::Metastamp::Time
55
+ end
56
+ ```
57
+
58
+ ```ruby
59
+ MyEvent.create(starts_at: Time.now, ends_at: Time.now + 1.day)
60
+
61
+ event = MyEvent.where(:starts_at.lt => Time.now, :ends_at.gt => Time.now).one
62
+ event.starts_at # => Time
63
+ event.ends_at # => Time
64
+ ```
65
+
66
+ Data Stored
67
+ =========================
68
+
69
+ When you define a `Mongoid::Metastamp::Time` field, the following meta fields also get stored inside its hash:
12
70
 
13
- So you could query all possible events between some range and then run a conversion on each result to narrow it down, but that makes servers die and developers cry.
14
- With mongoid-metastamp you get a custom timestamp field that performs conversions when you save, and then stores the metadata in a MongoDB friendly way for easy querying.
71
+ * `time` (Date)
72
+ * `normalized` (Date)
73
+ * `year` (Int)
74
+ * `month` (Int)
75
+ * `day` (Int)
76
+ * `wday` (Int)
77
+ * `hour` (Int)
78
+ * `min` (Int)
79
+ * `sec` (Int)
80
+ * `zone` (String)
81
+ * `offset` (Int)
15
82
 
16
- Storage
83
+
84
+ The `time` meta-field stores whatever you assign the field to.
85
+ It will also be the value deserialized when you access the field.
86
+
87
+ ```ruby
88
+ field :timestamp, type: Mongoid::Metastamp::Time
89
+ ```
90
+
91
+ For a field called `timestamp`, you can access the raw metadata fields like this:
92
+
93
+ ```ruby
94
+ event = MyEvent.new(starts_at: "2011-10-05 10:00:00 -0700")
95
+ event['timestamp']['month'] # => 10
96
+ event['timestamp']['day'] # => 5
97
+ event['timestamp']['year'] # => 2011
98
+ event['timestamp']['zone'] # => "-07:00"
99
+ ```
100
+
101
+ The `normalized` meta-field is the time normalized to a UTC value.
102
+ This is useful when you want to query ignoring local offsets.
103
+
104
+ ```ruby
105
+ eastern_event = MyEvent.new(timestamp: "2011-10-05 10:00:00 -0400")
106
+ pacific_event = MyEvent.new(timestamp: "2011-10-05 10:00:00 -0700")
107
+
108
+ eastern_event['timestamp']['time'] # => 2011-10-05 14:00:00 UTC
109
+ eastern_event['timestamp']['normalized'] # => 2011-10-05 10:00:00 UTC
110
+
111
+ pacific_event['timestamp']['time'] # => 2011-10-05 17:00:00 UTC
112
+ pacific_event['timestamp']['normalized'] # => 2011-10-05 10:00:00 UTC
113
+ ```
114
+
115
+
116
+ Querying
17
117
  =========================
18
- (What metadata should we store?)
19
118
 
20
- * in_zone (Date)
21
- * normalized (Date)
22
- * year (Int)
23
- * month (Int)
24
- * day (Int)
25
- * hour (Int)
26
- * min (Int)
27
- * sec (Int)
28
- * time_zone (String)
119
+ Since the `time` meta-field is the default, it can be queried as either `timestamp` or `timestamp.time`:
120
+
121
+ ```ruby
122
+ good_old_days = Day.where(:timestamp.lt => 20.years.ago)
123
+ ```
124
+
125
+ or...
126
+
127
+ ```ruby
128
+ good_old_days = Day.where("timestamp.time" => { '$lt' => 20.years.ago })
129
+ ```
130
+
131
+ The other meta-fields need to be queried with the full syntax:
132
+
133
+ ```ruby
134
+ hump_days = Day.where("timestamp.wday" => 5)
135
+ => Only Wednesdays
136
+
137
+ after_noon_delights = Delight.where("timestamp.hour" => { '$gte' => 12, '$lte' => 15 })
138
+ => Only between 12pm and 3pm
139
+ ```
140
+ See [search specs](https://github.com/sporkd/mongoid-metastamp/blob/master/spec/time_search_spec.rb)
141
+ for more complete examples.
142
+
143
+
144
+ Todo
145
+ ======
146
+
147
+ * Add custom finders and scopes
148
+ * Migration tasks for existing time fields
149
+ * Additional types
150
+
151
+
152
+ License
153
+ ========
29
154
 
155
+ Copyright (c) 2011 Peter Gumeson.
156
+ See [LICENSE](https://github.com/sporkd/mongoid-metastamp/blob/master/LICENSE) for full license.
30
157
 
31
- (More to come)
@@ -8,40 +8,45 @@ module Mongoid #:nodoc:
8
8
 
9
9
  def deserialize(object)
10
10
  return nil if object.blank?
11
- super(object[:in_zone])
11
+ return super(object) if object.instance_of?(::Time)
12
+ super(object['time'])
12
13
  end
13
14
 
14
15
  def serialize(object)
16
+ return nil if object.blank?
15
17
  time = super(object)
16
- normalized_time = normalize_time(object)
18
+ date_time = parse_datetime(object)
17
19
  {
18
- in_zone: time,
19
- normalized: normalized_time,
20
- year: normalized_time.year,
21
- month: normalized_time.month,
22
- day: normalized_time.day,
23
- hour: normalized_time.hour,
24
- min: normalized_time.min,
25
- sec: normalized_time.sec
26
- }
20
+ time: time,
21
+ normalized: date_time.to_s.to_time,
22
+ year: date_time.year,
23
+ month: date_time.month,
24
+ day: date_time.day,
25
+ wday: date_time.wday,
26
+ hour: date_time.hour,
27
+ min: date_time.min,
28
+ sec: date_time.sec,
29
+ zone: date_time.zone,
30
+ offset: date_time.utc_offset
31
+ }.stringify_keys
27
32
  end
28
33
 
29
34
  protected
30
35
 
31
- def normalize_time(object)
32
- case object
36
+ def parse_datetime(value)
37
+ case value
33
38
  when ::String
34
- time = ::Time.parse(object)
35
- when ::DateTime
36
- time = ::Time.new(object.year, object.month, object.day, object.hour, object.min, object.sec)
39
+ ::DateTime.parse(value)
40
+ when ::Time
41
+ offset = ActiveSupport::TimeZone.seconds_to_utc_offset(value.utc_offset)
42
+ ::DateTime.new(value.year, value.month, value.day, value.hour, value.min, value.sec, offset)
37
43
  when ::Date
38
- time = ::Time.new(object.year, object.month, object.day)
44
+ ::DateTime.new(value.year, value.month, value.day)
39
45
  when ::Array
40
- time = ::Time.new(*object)
46
+ ::DateTime.new(*value)
41
47
  else
42
- time = object
48
+ value
43
49
  end
44
- ::Time.parse(time.iso8601.sub(/-(\d\d:\d\d)$/, "-00:00"))
45
50
  end
46
51
  end
47
52
  end
@@ -1,5 +1,5 @@
1
1
  module Mongoid #:nodoc:
2
2
  module Metastamp
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["Peter Gumeson"]
10
10
  s.email = ["gumeson@gmail.com"]
11
11
  s.homepage = "http://rubygems.org/gems/mongoid-metastamp"
12
- s.summary = %q{ Store and query more useful information about your Mongoid timestamps }
13
- s.description = %q{ Provides enhanced meta-timestamps for mongoid that allow querying by day, month, year, min, sec, or by local vs. universal timezone. }
12
+ s.summary = %q{ Store and query more useful information about your Mongoid timestamps. }
13
+ s.description = %q{ Provides Mongoid with enhanced meta-timestamps that store additional parsed time metadata, allowing more powerful querying on specific time fields and across normalized time zones. }
14
14
 
15
15
  s.rubyforge_project = "mongoid-metastamp"
16
16
 
@@ -0,0 +1,70 @@
1
+ #encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Mongoid::Metastamp::Time" do
6
+
7
+ let :two_pm_pacific do
8
+ "2011-10-05T14:00:00-07:00"
9
+ end
10
+
11
+ describe "compatibility with Time class" do
12
+
13
+ class Legacy
14
+ include Mongoid::Document
15
+ field :timestamp, type: Time
16
+ end
17
+
18
+ let :instance do
19
+ Legacy.create(timestamp: two_pm_pacific).reload
20
+ end
21
+
22
+ context "before upgrade" do
23
+
24
+ it "should have a timestamp" do
25
+ instance.timestamp.should == Time.parse(two_pm_pacific)
26
+ end
27
+
28
+ it "should store timestamp as a Time" do
29
+ instance['timestamp'].class.should == Time
30
+ end
31
+
32
+ end
33
+
34
+ context "after Mongoid::Metastamp upgrade" do
35
+
36
+ before :each do
37
+ instance
38
+ Legacy.field(:timestamp, type: Mongoid::Metastamp::Time)
39
+ end
40
+
41
+ let :legacy do
42
+ Legacy.find(instance.id)
43
+ end
44
+
45
+ it "should still be able to read legacy timestamps" do
46
+ legacy.timestamp.should == Time.parse(two_pm_pacific)
47
+ end
48
+
49
+ describe "updating timestamp with the same time" do
50
+
51
+ before :each do
52
+ legacy.update_attribute(:timestamp, two_pm_pacific)
53
+ end
54
+
55
+ it "should now store timestamp as a Hash" do
56
+ legacy['timestamp'].class.should == Hash
57
+ legacy['timestamp']['time'].should == Time.parse(two_pm_pacific)
58
+ end
59
+
60
+ it "should still be compatible with the legacy timestamp" do
61
+ legacy.timestamp.should == Time.parse(two_pm_pacific)
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,211 @@
1
+ #encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Mongoid::Metastamp::Time" do
6
+
7
+ let :ten_am_utc do
8
+ "2011-10-05T10:00:00-00:00"
9
+ end
10
+
11
+ let :ten_am_eastern do
12
+ "2011-10-05T10:00:00-04:00"
13
+ end
14
+
15
+ let :ten_am_pacific do
16
+ "2011-10-05T10:00:00-07:00"
17
+ end
18
+
19
+ context "given a 10:00 eastern and a 10:00 pacific timestamp" do
20
+
21
+ before :each do
22
+ @eastern_event = Event.create(timestamp: ten_am_eastern)
23
+ @pacific_event = Event.create(timestamp: ten_am_pacific)
24
+ end
25
+
26
+ describe "searching by timestamp" do
27
+
28
+ it "should not return any events when searching a 10:00 UTC range" do
29
+ Event.where(
30
+ :timestamp.gt => Time.parse(ten_am_utc) - 1.second,
31
+ :timestamp.lt => Time.parse(ten_am_utc) + 1.second
32
+ ).to_a.should == []
33
+ end
34
+
35
+ it "should only return the ET event when searching a 10:00 ET range" do
36
+ Event.where(
37
+ :timestamp.gt => Time.parse(ten_am_eastern) - 1.second,
38
+ :timestamp.lt => Time.parse(ten_am_eastern) + 1.second
39
+ ).to_a.should == [@eastern_event]
40
+ end
41
+
42
+ it "should only return the PT event when searching a 10:00 PT range" do
43
+ Event.where(
44
+ :timestamp.gt => Time.parse(ten_am_pacific) - 1.second,
45
+ :timestamp.lt => Time.parse(ten_am_pacific) + 1.second
46
+ ).to_a.should == [@pacific_event]
47
+ end
48
+
49
+ end
50
+
51
+ describe "searching by timestamp.time" do
52
+
53
+ it "should not return any events when searching a 10:00 UTC range" do
54
+ Event.where(
55
+ "timestamp.time" => {
56
+ '$gt' => Time.parse(ten_am_utc) - 1.second,
57
+ '$lt' => Time.parse(ten_am_utc) + 1.second
58
+ }
59
+ ).to_a.should == []
60
+ end
61
+
62
+ it "should only return the ET event when searching a 10:00 ET range" do
63
+ Event.where(
64
+ "timestamp.time" => {
65
+ '$gt' => Time.parse(ten_am_eastern) - 1.second,
66
+ '$lt' => Time.parse(ten_am_eastern) + 1.second
67
+ }
68
+ ).to_a.should == [@eastern_event]
69
+ end
70
+
71
+ it "should only return the PT event when searching a 10:00 PT range" do
72
+ Event.where(
73
+ "timestamp.time" => {
74
+ '$gt' => Time.parse(ten_am_pacific) - 1.second,
75
+ '$lt' => Time.parse(ten_am_pacific) + 1.second
76
+ }
77
+ ).to_a.should == [@pacific_event]
78
+ end
79
+
80
+ end
81
+
82
+ describe "searching by timestamp.normalized" do
83
+
84
+ it "should return both events when searching a 10:00 UTC range" do
85
+ Event.where(
86
+ "timestamp.normalized" => {
87
+ '$gt' => Time.parse(ten_am_utc) - 1.second,
88
+ '$lt' => Time.parse(ten_am_utc) + 1.second
89
+ }
90
+ ).to_a.should == [@eastern_event, @pacific_event]
91
+ end
92
+
93
+ it "should not return any events when searching a 10:00 ET range" do
94
+ Event.where(
95
+ "timestamp.normalized" => {
96
+ '$gt' => Time.parse(ten_am_eastern) - 1.second,
97
+ '$lt' => Time.parse(ten_am_eastern) + 1.second
98
+ }
99
+ ).to_a.should == []
100
+ end
101
+
102
+ it "should not return any events when searching a 10:00 PT range" do
103
+ Event.where(
104
+ "timestamp.normalized" => {
105
+ '$gt' => Time.parse(ten_am_pacific) - 1.second,
106
+ '$lt' => Time.parse(ten_am_pacific) + 1.second
107
+ }
108
+ ).to_a.should == []
109
+ end
110
+
111
+ end
112
+
113
+ describe "searching by timestamp.year" do
114
+
115
+ it "should not return any events for 2010" do
116
+ Event.where("timestamp.year" => 2010).count.should == 0
117
+ end
118
+
119
+ it "should return both events for 2011" do
120
+ Event.where("timestamp.year" => 2011).count.should == 2
121
+ end
122
+
123
+ end
124
+
125
+ describe "searching by timestamp.month" do
126
+
127
+ it "should not return any events when before October" do
128
+ Event.where("timestamp.month" => {'$lt' => 10}).count.should == 0
129
+ end
130
+
131
+ it "should return both events for October" do
132
+ Event.where("timestamp.month" => 10).count.should == 2
133
+ end
134
+
135
+ end
136
+
137
+ describe "searching by timestamp.day" do
138
+
139
+ it "should not return any events when after the 5th" do
140
+ Event.where("timestamp.day" => {'$gt' => 5}).count.should == 0
141
+ end
142
+
143
+ it "should return both events for the 5th" do
144
+ Event.where("timestamp.day" => 5).count.should == 2
145
+ end
146
+
147
+ end
148
+
149
+ describe "searching by timestamp.wday" do
150
+
151
+ it "should not return any events when thurs - tues" do
152
+ Event.where("timestamp.wday" => {'$gte' => 4, '$lte' => 2}).count.should == 0
153
+ end
154
+
155
+ it "should return both events for wed" do
156
+ Event.where("timestamp.wday" => 3).count.should == 2
157
+ end
158
+
159
+ end
160
+
161
+ describe "searching by timestamp.hour" do
162
+
163
+ it "should not return any events when before 10 AM" do
164
+ Event.where("timestamp.hour" => {'$lt' => 10}).count.should == 0
165
+ end
166
+
167
+ it "should return both events for 10 AM" do
168
+ Event.where("timestamp.hour" => 10).count.should == 2
169
+ end
170
+
171
+ end
172
+
173
+ describe "searching by timestamp.min" do
174
+
175
+ it "should not return any events when after 1 minute" do
176
+ Event.where("timestamp.min" => {'$gte' => 1}).count.should == 0
177
+ end
178
+
179
+ it "should return both events for 0" do
180
+ Event.where("timestamp.min" => 0).count.should == 2
181
+ end
182
+
183
+ end
184
+
185
+ describe "searching by timestamp.sec" do
186
+
187
+ it "should not return any events when after 1 second" do
188
+ Event.where("timestamp.sec" => {'$gte' => 1}).count.should == 0
189
+ end
190
+
191
+ it "should return both events for 0" do
192
+ Event.where("timestamp.sec" => 0).count.should == 2
193
+ end
194
+
195
+ end
196
+
197
+ describe "searching by timestamp.zone" do
198
+
199
+ it "should return only the eastern event when searching -04:00" do
200
+ Event.where("timestamp.zone" => "-04:00").to_a.should == [@eastern_event]
201
+ end
202
+
203
+ it "should return only the pacific event when searching -07:00" do
204
+ Event.where("timestamp.zone" => "-07:00").to_a.should == [@pacific_event]
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+
211
+ end
@@ -0,0 +1,222 @@
1
+ #encoding: utf-8
2
+
3
+ require "spec_helper"
4
+
5
+ describe "Mongoid::Metastamp::Time" do
6
+
7
+ context "when storing nil" do
8
+
9
+ context "on initialization" do
10
+
11
+ let :event do
12
+ Event.new(timestamp: nil)
13
+ end
14
+
15
+ describe "on serialization" do
16
+
17
+ it "should store timestamp as nil" do
18
+ event['timestamp'].should == nil
19
+ end
20
+
21
+ end
22
+
23
+ describe "on deserialization" do
24
+
25
+ it "timestamp should return nil" do
26
+ event.timestamp.should == nil
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ context "on creation" do
34
+
35
+ let :event do
36
+ Event.create(timestamp: nil).reload
37
+ end
38
+
39
+ describe "on serialization" do
40
+
41
+ it "should store timestamp as nil" do
42
+ event['timestamp'].should == nil
43
+ end
44
+
45
+ end
46
+
47
+ describe "on deserialization" do
48
+
49
+ it "timestamp should return nil" do
50
+ event.timestamp.should == nil
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ [0, 12, 23].each do |hour|
60
+
61
+ ["+00:00", "-04:00", "-07:00", "+13:00"].each do |zone|
62
+
63
+ time_utc = Time.new(2011, 12, 31, hour, 0, 0, '-00:00')
64
+ time = Time.new(2011, 12, 31, hour, 0, 0, zone)
65
+
66
+ context "storing time #{ time }" do
67
+
68
+ {
69
+ "String" => time.to_s,
70
+ "iso8601" => time.iso8601,
71
+ "Time" => time
72
+ }.each do |format, timestamp|
73
+
74
+ context "formatted as #{ format } (#{ timestamp })" do
75
+
76
+ context "on initialization" do
77
+
78
+ let :event do
79
+ Event.new(timestamp: timestamp)
80
+ end
81
+
82
+ describe "on serialization" do
83
+
84
+ it "should store timestamp.time" do
85
+ event['timestamp']['time'].should == time
86
+ end
87
+
88
+ it "should store timestamp.normalized" do
89
+ event['timestamp']['normalized'].should == time_utc
90
+ end
91
+
92
+ it "should store timestamp.year as 2011" do
93
+ event['timestamp']['year'].should == 2011
94
+ end
95
+
96
+ it "should store timestamp.month as 12" do
97
+ event['timestamp']['month'].should == 12
98
+ end
99
+
100
+ it "should store timestamp.day as 31" do
101
+ event['timestamp']['day'].should == 31
102
+ end
103
+
104
+ it "should store timestamp.wday as 6 (Saturday)" do
105
+ event['timestamp']['wday'].should == 6
106
+ end
107
+
108
+ it "should store timestamp.hour as #{ hour }" do
109
+ event['timestamp']['hour'].should == hour
110
+ end
111
+
112
+ it "should store timestamp.min as 0" do
113
+ event['timestamp']['min'].should == 0
114
+ end
115
+
116
+ it "should store timestamp.sec as 0" do
117
+ event['timestamp']['sec'].should == 0
118
+ end
119
+
120
+ it "should store timestamp.zone as #{ zone }" do
121
+ event['timestamp']['zone'].should == zone
122
+ end
123
+
124
+ it "should store timestamp.offset as #{ (zone.to_i * 60 * 60) }" do
125
+ event['timestamp']['offset'].should == (zone.to_i * 60 * 60)
126
+ end
127
+
128
+ end
129
+
130
+ describe "on deserialization" do
131
+
132
+ it "timestamp should return #{ time }" do
133
+ event.timestamp.should == time
134
+ end
135
+
136
+ it "timestamp should return time in UTC" do
137
+ event.timestamp.zone.should == "UTC"
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+
144
+ context "on creation" do
145
+
146
+ let :event do
147
+ Event.create(timestamp: timestamp).reload
148
+ end
149
+
150
+ describe "on serialization" do
151
+
152
+ it "should store timestamp.time" do
153
+ event['timestamp']['time'].should == time
154
+ end
155
+
156
+ it "should store timestamp.normalized" do
157
+ event['timestamp']['normalized'].should == time_utc
158
+ end
159
+
160
+ it "should store timestamp.year as 2011" do
161
+ event['timestamp']['year'].should == 2011
162
+ end
163
+
164
+ it "should store timestamp.month as 12" do
165
+ event['timestamp']['month'].should == 12
166
+ end
167
+
168
+ it "should store timestamp.day as 31" do
169
+ event['timestamp']['day'].should == 31
170
+ end
171
+
172
+ it "should store timestamp.wday as 6 (Saturday)" do
173
+ event['timestamp']['wday'].should == 6
174
+ end
175
+
176
+ it "should store timestamp.hour as #{ hour }" do
177
+ event['timestamp']['hour'].should == hour
178
+ end
179
+
180
+ it "should store timestamp.min as 0" do
181
+ event['timestamp']['min'].should == 0
182
+ end
183
+
184
+ it "should store timestamp.sec as 0" do
185
+ event['timestamp']['sec'].should == 0
186
+ end
187
+
188
+ it "should store timestamp.zone as #{ zone }" do
189
+ event['timestamp']['zone'].should == zone
190
+ end
191
+
192
+ it "should store timestamp.offset as #{ (zone.to_i * 60 * 60) }" do
193
+ event['timestamp']['offset'].should == (zone.to_i * 60 * 60)
194
+ end
195
+
196
+ end
197
+
198
+ describe "on deserialization" do
199
+
200
+ it "timestamp should return #{ time }" do
201
+ event.timestamp.should == time
202
+ end
203
+
204
+ it "timestamp should return time in UTC" do
205
+ event.timestamp.zone.should == "UTC"
206
+ end
207
+
208
+ end
209
+
210
+ end
211
+
212
+ end
213
+
214
+ end
215
+
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+
222
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mongoid-metastamp
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Peter Gumeson
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-10-08 00:00:00 -07:00
13
+ date: 2011-10-11 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -57,7 +57,7 @@ dependencies:
57
57
  version: "2.6"
58
58
  type: :development
59
59
  version_requirements: *id004
60
- description: " Provides enhanced meta-timestamps for mongoid that allow querying by day, month, year, min, sec, or by local vs. universal timezone. "
60
+ description: " Provides Mongoid with enhanced meta-timestamps that store additional parsed time metadata, allowing more powerful querying on specific time fields and across normalized time zones. "
61
61
  email:
62
62
  - gumeson@gmail.com
63
63
  executables: []
@@ -70,6 +70,7 @@ files:
70
70
  - .gitignore
71
71
  - .rspec
72
72
  - Gemfile
73
+ - LICENSE
73
74
  - README.md
74
75
  - Rakefile
75
76
  - lib/mongoid-metastamp.rb
@@ -78,9 +79,11 @@ files:
78
79
  - lib/mongoid/metastamp/time.rb
79
80
  - lib/mongoid/metastamp/version.rb
80
81
  - mongoid-metastamp.gemspec
81
- - spec/metastamp_spec.rb
82
82
  - spec/models/event.rb
83
83
  - spec/spec_helper.rb
84
+ - spec/time_compatibility_spec.rb
85
+ - spec/time_search_spec.rb
86
+ - spec/time_storage_spec.rb
84
87
  has_rdoc: true
85
88
  homepage: http://rubygems.org/gems/mongoid-metastamp
86
89
  licenses: []
@@ -108,8 +111,10 @@ rubyforge_project: mongoid-metastamp
108
111
  rubygems_version: 1.6.2
109
112
  signing_key:
110
113
  specification_version: 3
111
- summary: Store and query more useful information about your Mongoid timestamps
114
+ summary: Store and query more useful information about your Mongoid timestamps.
112
115
  test_files:
113
- - spec/metastamp_spec.rb
114
116
  - spec/models/event.rb
115
117
  - spec/spec_helper.rb
118
+ - spec/time_compatibility_spec.rb
119
+ - spec/time_search_spec.rb
120
+ - spec/time_storage_spec.rb
@@ -1,57 +0,0 @@
1
- #encoding: utf-8
2
-
3
- require "spec_helper"
4
-
5
- describe Mongoid::Metastamp do
6
-
7
- let :ten_am_utc do
8
- "2011-10-05T10:00:00-00:00"
9
- end
10
-
11
- let :ten_am_eastern do
12
- "2011-10-05T10:00:00-04:00"
13
- end
14
-
15
- let :ten_am_pacific do
16
- "2011-10-05T10:00:00-07:00"
17
- end
18
-
19
- describe "with custom field of type Mongoid::Metastamp::Time" do
20
-
21
- context "named timestamp" do
22
-
23
- context "when set to 10:00 AM PST" do
24
-
25
- let :pst_event do
26
- Event.create(timestamp: ten_am_pacific)
27
- end
28
-
29
- it "should have a timestamp field" do
30
- pst_event.should respond_to(:timestamp)
31
- end
32
-
33
- it "should deserialize the timestamp as 10 AM PST" do
34
- pst_event.timestamp.should == Time.parse(ten_am_pacific)
35
- end
36
-
37
- it "should be searchable by timestamp.in_zone" do
38
- Event.where(
39
- "timestamp.in_zone" => { '$gt' => Time.parse(ten_am_pacific) - 1.minute },
40
- "timestamp.in_zone" => { '$lt' => Time.parse(ten_am_pacific) + 1.minute }
41
- ).should == [pst_event]
42
- end
43
-
44
- it "should be searchable by timestamp.normalized" do
45
- Event.where(
46
- "timestamp.normalized" => { '$gt' => Time.parse(ten_am_utc) - 1.minute },
47
- "timestamp.normalized" => { '$lt' => Time.parse(ten_am_utc) + 1.minute }
48
- ).should == [pst_event]
49
- end
50
-
51
- end
52
-
53
- end
54
-
55
- end
56
-
57
- end