trackoid 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +3 -0
- data/README.rdoc +130 -0
- data/VERSION +1 -1
- data/lib/trackoid/aggregates.rb +6 -2
- data/lib/trackoid/core_ext/range.rb +53 -0
- data/lib/trackoid/core_ext/time.rb +46 -0
- data/lib/trackoid/core_ext.rb +3 -0
- data/lib/trackoid/errors.rb +11 -1
- data/lib/trackoid/reader_extender.rb +64 -0
- data/lib/trackoid/readers.rb +36 -24
- data/lib/trackoid/tracker.rb +44 -22
- data/lib/trackoid/tracker_aggregates.rb +1 -0
- data/lib/trackoid/tracking.rb +5 -2
- data/lib/trackoid.rb +3 -0
- data/spec/aggregates_spec.rb +16 -7
- data/spec/ext/range_spec.rb +110 -0
- data/spec/ext/time_spec.rb +142 -0
- data/spec/reader_extender_spec.rb +34 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/timezone_spec.rb +249 -0
- data/spec/trackoid_spec.rb +23 -13
- data/trackoid.gemspec +15 -2
- metadata +16 -3
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Range do
|
4
|
+
describe "using the diff method" do
|
5
|
+
it "should work for normal ranges" do
|
6
|
+
(0..2).diff.should == 3
|
7
|
+
(0...2).diff.should == 2
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should work for Time ranges (DAYS)" do
|
11
|
+
now = Time.now
|
12
|
+
inc_range = now..(now + 1*Range::DAYS)
|
13
|
+
exc_range = now...(now + 1*Range::DAYS)
|
14
|
+
|
15
|
+
inc_range.diff.should == 2
|
16
|
+
exc_range.diff.should == 1
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should work for Time ranges (HOURS)" do
|
20
|
+
now = Time.now
|
21
|
+
inc_range = now..(now + 10*Range::HOURS)
|
22
|
+
exc_range = now...(now + 10*Range::HOURS)
|
23
|
+
|
24
|
+
inc_range.diff(Range::HOURS).should == 11
|
25
|
+
exc_range.diff(Range::HOURS).should == 10
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should also work when using helper methods" do
|
29
|
+
now = Time.now
|
30
|
+
inc_range = now..(now + 10*Range::HOURS)
|
31
|
+
exc_range = now...(now + 10*Range::HOURS)
|
32
|
+
|
33
|
+
inc_range.hour_diff.should == 11
|
34
|
+
exc_range.hour_diff.should == 10
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should behave like normal ranges for 1 element" do
|
38
|
+
now = Time.now
|
39
|
+
inc_range = now..now
|
40
|
+
exc_range = now...now
|
41
|
+
|
42
|
+
inc_range.diff.should == 1
|
43
|
+
exc_range.diff.should == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should keep Time UTC and DST properties" do
|
47
|
+
date1 = Time.local(2011, 4, 1, 0, 0)
|
48
|
+
date2 = Time.utc(2011, 4, 1, 0, 0)
|
49
|
+
|
50
|
+
range1 = date1..date1
|
51
|
+
range2 = date2..date2
|
52
|
+
|
53
|
+
range1.first.should_not be_utc
|
54
|
+
range1.first.should be_dst
|
55
|
+
range2.first.should be_utc
|
56
|
+
range2.first.should_not be_dst
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "using the map method" do
|
61
|
+
it "should work for normal ranges (using enumerator)" do
|
62
|
+
inc_result = (0..2).map.to_a
|
63
|
+
inc_result.should == [0, 1, 2]
|
64
|
+
|
65
|
+
exc_result = (0...2).map.to_a
|
66
|
+
exc_result.should == [0, 1]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should work for normal ranges (using block)" do
|
70
|
+
inc_result = (0..2).map {|e| e}
|
71
|
+
inc_result.should == [0, 1, 2]
|
72
|
+
|
73
|
+
exc_result = (0...2).map {|e| e}
|
74
|
+
exc_result.should == [0, 1]
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should work for Time ranges" do
|
78
|
+
date = Time.utc(2011, 4, 1, 0, 0)
|
79
|
+
inc_range = date..(date + 5*Range::DAYS)
|
80
|
+
inc_result = inc_range.map {|d| d.to_i_timestamp}
|
81
|
+
inc_result.should == [15065, 15066, 15067, 15068, 15069, 15070]
|
82
|
+
|
83
|
+
exc_range = date...(date + 5*Range::DAYS)
|
84
|
+
exc_result = exc_range.map {|d| d.to_i_timestamp}
|
85
|
+
exc_result.should == [15065, 15066, 15067, 15068, 15069]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should work for empty excluding Time ranges" do
|
89
|
+
date = Time.utc(2011, 4, 1, 0, 0)
|
90
|
+
exc_range = date...date
|
91
|
+
exc_result = exc_range.map {|d| d.to_i_timestamp}
|
92
|
+
exc_result.should == []
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should return an array if no block given" do
|
96
|
+
date = Time.utc(2011, 4, 1, 0, 0)
|
97
|
+
result = (date..(date + 5*Range::DAYS)).map
|
98
|
+
result.count.should == 6
|
99
|
+
|
100
|
+
# Result is now an array
|
101
|
+
result.map(&:to_i_timestamp).should == [15065, 15066, 15067, 15068, 15069, 15070]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should also work using helper methods" do
|
105
|
+
date = Time.utc(2011, 4, 1, 0, 0)
|
106
|
+
result = (date..(date + 5*Range::HOURS)).hour_map
|
107
|
+
result.count.should == 6
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Time do
|
4
|
+
describe "when working with UTC dates" do
|
5
|
+
it "should return the correct timestamp" do
|
6
|
+
time1 = Time.utc(2011, 1, 1, 0, 0, 0)
|
7
|
+
time1.to_i_timestamp.should == 14975
|
8
|
+
|
9
|
+
time2 = Time.utc(2011, 1, 1, 23, 59, 59)
|
10
|
+
time2.to_i_timestamp.should == 14975
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return the correct hours" do
|
14
|
+
time1 = Time.utc(2011, 1, 1, 0, 0, 0)
|
15
|
+
time1.to_i_hour.should == 0
|
16
|
+
|
17
|
+
time2 = Time.utc(2011, 1, 1, 23, 59, 59)
|
18
|
+
time2.to_i_hour.should == 23
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should convert back with timestamps and hours" do
|
22
|
+
t = Time.from_key(14975, 23).utc
|
23
|
+
t.to_s.should == "2011-01-01 23:00:00 UTC"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should work also on ranges (dates)" do
|
27
|
+
time1 = Time.utc(2011, 1, 1, 0, 0, 0)
|
28
|
+
range = time1...(time1 + 10*Range::DAYS)
|
29
|
+
range.map(&:to_i_timestamp).should == [14975, 14976, 14977, 14978, 14979, 14980, 14981, 14982, 14983, 14984]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should work also on ranges (hours)" do
|
33
|
+
range = Time.utc(2011, 1, 1)...Time.utc(2011, 1, 2)
|
34
|
+
|
35
|
+
# With Range::HOURS
|
36
|
+
range.map(Range::HOURS){|d| d.to_i_hour}.should == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
|
37
|
+
|
38
|
+
# With ActiveSupport Numeric extensions
|
39
|
+
range.map(1.hour){|d| d.to_i_hour}.should == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should iterate for a day and return the correct UTC keys" do
|
43
|
+
today = Time.utc(2011, 1, 1).whole_day
|
44
|
+
today.diff(Range::HOURS).should == 24
|
45
|
+
today.map(Range::HOURS) {|d| d.to_key}.should == [
|
46
|
+
"14975.0", "14975.1", "14975.2", "14975.3", "14975.4", "14975.5",
|
47
|
+
"14975.6", "14975.7", "14975.8", "14975.9", "14975.10", "14975.11",
|
48
|
+
"14975.12", "14975.13", "14975.14", "14975.15", "14975.16", "14975.17",
|
49
|
+
"14975.18", "14975.19", "14975.20", "14975.21", "14975.22", "14975.23"
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should iterate for a day and return the correct UTC keys (Helper methods)" do
|
54
|
+
today = Time.utc(2011, 1, 1).whole_day
|
55
|
+
today.hour_diff.should == 24
|
56
|
+
today.hour_map {|d| d.to_key}.should == [
|
57
|
+
"14975.0", "14975.1", "14975.2", "14975.3", "14975.4", "14975.5",
|
58
|
+
"14975.6", "14975.7", "14975.8", "14975.9", "14975.10", "14975.11",
|
59
|
+
"14975.12", "14975.13", "14975.14", "14975.15", "14975.16", "14975.17",
|
60
|
+
"14975.18", "14975.19", "14975.20", "14975.21", "14975.22", "14975.23"
|
61
|
+
]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "when working with TZ dates (Europe)" do
|
66
|
+
before do
|
67
|
+
ENV["TZ"] = "Europe/Madrid"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return the correct timestamp" do
|
71
|
+
# NOTE: January 1, 2011 00:00 GMT+1 Timezone corresponds to: December, 31 2010 23:00 UTC
|
72
|
+
time1 = Time.local(2011, 1, 1, 0, 0, 0)
|
73
|
+
time1.to_i_timestamp.should == 14974
|
74
|
+
|
75
|
+
time2 = Time.local(2011, 1, 1, 23, 59, 59)
|
76
|
+
time2.to_i_timestamp.should == 14975
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return the correct hours" do
|
80
|
+
time1 = Time.local(2011, 1, 1, 0, 0, 0)
|
81
|
+
time1.to_i_hour.should == 23 # This is for the previous day
|
82
|
+
|
83
|
+
time2 = Time.local(2011, 1, 1, 23, 59, 59)
|
84
|
+
time2.to_i_hour.should == 22
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should convert back with timestamps and hours" do
|
88
|
+
t = Time.from_key(14975, 23)
|
89
|
+
t.to_s.should == "2011-01-02 00:00:00 +0100"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "when working with TZ dates (America)" do
|
94
|
+
before do
|
95
|
+
ENV["TZ"] = "America/Los_Angeles"
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should return the correct timestamp" do
|
99
|
+
time1 = Time.local(2011, 1, 1, 0, 0, 0)
|
100
|
+
time1.to_i_timestamp.should == 14975
|
101
|
+
|
102
|
+
# Note: January 1, 2011 23:00 PST Timezone corresponds to: January, 2 2010 07:00 UTC
|
103
|
+
time2 = Time.local(2011, 1, 1, 23, 59, 59)
|
104
|
+
time2.to_i_timestamp.should == 14976
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should return the correct hours" do
|
108
|
+
time1 = Time.local(2011, 1, 1, 0, 0, 0)
|
109
|
+
time1.to_i_hour.should == 8
|
110
|
+
|
111
|
+
time2 = Time.local(2011, 1, 1, 23, 59, 59)
|
112
|
+
time2.to_i_hour.should == 7 # This is for the next day
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should convert back with timestamps and hours" do
|
116
|
+
t = Time.from_key(14976, 7)
|
117
|
+
t.to_s.should == "2011-01-01 23:00:00 -0800"
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should iterate for a day and return the correct UTC keys" do
|
121
|
+
today = Time.local(2011, 1, 1).whole_day
|
122
|
+
today.map(Range::HOURS) {|d| d.to_key}.should == [
|
123
|
+
"14975.8", "14975.9", "14975.10", "14975.11", "14975.12", "14975.13",
|
124
|
+
"14975.14", "14975.15", "14975.16", "14975.17", "14975.18",
|
125
|
+
"14975.19", "14975.20", "14975.21", "14975.22", "14975.23",
|
126
|
+
"14976.0", "14976.1", "14976.2", "14976.3", "14976.4", "14976.5",
|
127
|
+
"14976.6", "14976.7"
|
128
|
+
]
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should iterate for a day and return the correct UTC keys (Helper methods)" do
|
132
|
+
today = Time.local(2011, 1, 1).whole_day
|
133
|
+
today.hour_map {|d| d.to_key}.should == [
|
134
|
+
"14975.8", "14975.9", "14975.10", "14975.11", "14975.12", "14975.13",
|
135
|
+
"14975.14", "14975.15", "14975.16", "14975.17", "14975.18",
|
136
|
+
"14975.19", "14975.20", "14975.21", "14975.22", "14975.23",
|
137
|
+
"14976.0", "14976.1", "14976.2", "14976.3", "14976.4", "14976.5",
|
138
|
+
"14976.6", "14976.7"
|
139
|
+
]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Mongoid::Tracking::ReaderExtender do
|
4
|
+
it "should behave like a number" do
|
5
|
+
num = Mongoid::Tracking::ReaderExtender.new(5, [])
|
6
|
+
num.should == 5
|
7
|
+
num.should < 10
|
8
|
+
(num * 10).should == 50
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to add additional data to it" do
|
12
|
+
num = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
13
|
+
num.hourly.should == [1, 2, 3, 4]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be able to sum two ReadersExtenders" do
|
17
|
+
a = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
18
|
+
b = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
19
|
+
c = a + b
|
20
|
+
c.should == 10
|
21
|
+
c.hourly.should == [2, 4, 6, 8]
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be able to sum more than two ReadersExtenders" do
|
25
|
+
a = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
26
|
+
b = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
27
|
+
c = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
28
|
+
d = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
29
|
+
e = Mongoid::Tracking::ReaderExtender.new(5, [1, 2, 3, 4])
|
30
|
+
f = a + b + c + d + e
|
31
|
+
f.should == 25
|
32
|
+
f.hourly.should == [5, 10, 15, 20]
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -15,7 +15,7 @@ Mongoid.configure do |config|
|
|
15
15
|
name = "trackoid_test"
|
16
16
|
host = "localhost"
|
17
17
|
port = "27017"
|
18
|
-
#
|
18
|
+
# config.master = Mongo::Connection.new(host, port, :logger => Logger.new(STDOUT)).db(name)
|
19
19
|
config.master = Mongo::Connection.new.db(name)
|
20
20
|
end
|
21
21
|
|
@@ -0,0 +1,249 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Mongoid::Tracking do
|
4
|
+
describe "Testing the system TZ for Europe/Madrid" do
|
5
|
+
before do
|
6
|
+
ENV['TZ'] = 'Europe/Madrid'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should convert dates to UTC" do
|
10
|
+
t = Time.now
|
11
|
+
t.should_not be_utc
|
12
|
+
t.utc
|
13
|
+
t.should be_utc
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should create dates in UTC" do
|
17
|
+
t = Time.utc(2011, 1, 1, 20, 30)
|
18
|
+
t.to_s.should == "2011-01-01 20:30:00 UTC"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should create dates in local time" do
|
22
|
+
t = Time.local(2011, 1, 1, 20, 30)
|
23
|
+
t.to_s.should == "2011-01-01 20:30:00 +0100"
|
24
|
+
t.utc_offset.should == 3600
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should detect daylight saving for local times" do
|
28
|
+
t = Time.local(2011, 6, 1, 20, 30)
|
29
|
+
t.should be_dst
|
30
|
+
t.to_s.should == "2011-06-01 20:30:00 +0200"
|
31
|
+
t.utc_offset.should == 7200
|
32
|
+
end
|
33
|
+
|
34
|
+
it "timestamps should be offset by the utc_offset" do
|
35
|
+
local = Time.local(2011, 1, 1, 0, 0)
|
36
|
+
utc = Time.utc(2011, 1, 1, 0, 0)
|
37
|
+
(utc - local).should == local.utc_offset
|
38
|
+
end
|
39
|
+
|
40
|
+
it "timestamps should be offset by the utc_offset even when daylight saving is on" do
|
41
|
+
local = Time.local(2011, 6, 1, 0, 0)
|
42
|
+
utc = Time.utc(2011, 6, 1, 0, 0)
|
43
|
+
local.should be_dst
|
44
|
+
utc.should_not be_dst
|
45
|
+
(local - utc).abs.should == local.utc_offset
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "Testing the system TZ for America/San Francisco" do
|
50
|
+
before do
|
51
|
+
ENV['TZ'] = 'America/Los_Angeles'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should convert dates to UTC" do
|
55
|
+
t = Time.now
|
56
|
+
t.should_not be_utc
|
57
|
+
t.utc
|
58
|
+
t.should be_utc
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should create dates in UTC" do
|
62
|
+
t = Time.utc(2011, 1, 1, 20, 30)
|
63
|
+
t.to_s.should == "2011-01-01 20:30:00 UTC"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should create dates in local time" do
|
67
|
+
t = Time.local(2011, 1, 1, 20, 30)
|
68
|
+
t.to_s.should == "2011-01-01 20:30:00 -0800"
|
69
|
+
t.utc_offset.should == -28800
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should detect daylight saving for local times" do
|
73
|
+
t = Time.local(2011, 6, 1, 20, 30)
|
74
|
+
t.should be_dst
|
75
|
+
t.to_s.should == "2011-06-01 20:30:00 -0700"
|
76
|
+
t.utc_offset.should == -25200
|
77
|
+
end
|
78
|
+
|
79
|
+
it "timestamps should be offset by the utc_offset" do
|
80
|
+
local = Time.local(2011, 1, 1, 0, 0)
|
81
|
+
utc = Time.utc(2011, 1, 1, 0, 0)
|
82
|
+
(utc - local).should == local.utc_offset
|
83
|
+
end
|
84
|
+
|
85
|
+
it "timestamps should be offset by the utc_offset even when daylight saving is on" do
|
86
|
+
local = Time.local(2011, 6, 1, 0, 0)
|
87
|
+
utc = Time.utc(2011, 6, 1, 0, 0)
|
88
|
+
local.should be_dst
|
89
|
+
utc.should_not be_dst
|
90
|
+
(utc - local).should == local.utc_offset
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "Testing the RAILS TZ capabilities" do
|
95
|
+
before do
|
96
|
+
ENV['TZ'] = nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should support time zone changing" do
|
100
|
+
Time.zone = ActiveSupport::TimeZone["America/Los_Angeles"]
|
101
|
+
|
102
|
+
local = Time.local(2011, 6, 1, 0, 0).in_time_zone
|
103
|
+
local.should be_dst
|
104
|
+
local.utc_offset.should == -25200
|
105
|
+
|
106
|
+
Time.zone = ActiveSupport::TimeZone["Europe/Madrid"]
|
107
|
+
local = Time.local(2011, 6, 1, 0, 0)
|
108
|
+
local.should be_dst
|
109
|
+
local.utc_offset.should == 7200
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should correctly handle UTC offseted dates" do
|
113
|
+
utc = Time.utc(2011, 6, 1, 0, 0)
|
114
|
+
utc_localized = Time.utc(2011, 6, 1, 0, 0) + 7200
|
115
|
+
|
116
|
+
(utc_localized - utc).should == 7200
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "Testing TZ data with real models" do
|
121
|
+
before(:all) do
|
122
|
+
class Test
|
123
|
+
include Mongoid::Document
|
124
|
+
include Mongoid::Tracking
|
125
|
+
|
126
|
+
field :name # Dummy field
|
127
|
+
track :visits
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
before do
|
132
|
+
Test.delete_all
|
133
|
+
Test.create(:name => "test")
|
134
|
+
@object_id = Test.first.id
|
135
|
+
@mock = Test.find(@object_id)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should correctly handle hours for my TimeZone" do
|
139
|
+
# WARNING: Volatile test, time dependant... Do not run at 00:00:00 :-)
|
140
|
+
t1 = Time.now.change(:hour => 0)
|
141
|
+
t2 = Time.now.change(:hour => 23)
|
142
|
+
|
143
|
+
@mock.visits.inc(t1)
|
144
|
+
@mock.visits.inc(t2)
|
145
|
+
@mock.visits.today.should == 2
|
146
|
+
@mock.visits.today.hourly.should == [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should correctly handle hours for UTC" do
|
150
|
+
# WARNING: Volatile test, time dependant... Do not run at 00:00:00 :-)
|
151
|
+
t1 = Time.now.utc.change(:hour => 0)
|
152
|
+
t2 = Time.now.utc.change(:hour => 23)
|
153
|
+
|
154
|
+
@mock.visits.inc(t1)
|
155
|
+
@mock.visits.inc(t2)
|
156
|
+
@mock.visits.on(Time.now.utc).should == 2
|
157
|
+
@mock.visits.on(Time.now.utc).hourly.should == [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
158
|
+
end
|
159
|
+
|
160
|
+
it "Hours in Europe/Madrid (Winter time) should be shifted by 1 hour from UTC" do
|
161
|
+
ENV["TZ"] = "Europe/Madrid"
|
162
|
+
|
163
|
+
time = Time.parse("2011-01-01")
|
164
|
+
t1 = time.change(:hour => 1)
|
165
|
+
t2 = time.change(:hour => 22)
|
166
|
+
|
167
|
+
@mock.visits.inc(t1)
|
168
|
+
@mock.visits.inc(t2)
|
169
|
+
|
170
|
+
# This test is interesting. We added with local TZ time but want to
|
171
|
+
# query shifted data on UTC. We need to read the expected span dates
|
172
|
+
# separately
|
173
|
+
visits = @mock.visits.on(time.utc..(time.utc + 1.day))
|
174
|
+
|
175
|
+
# Data from 2010-12-31 00:00:00 UTC up to 2011-12-31 23:59:59 UTC
|
176
|
+
visits.first.hourly.should == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
177
|
+
|
178
|
+
# Data from 2011-01-01 00:00:00 UTC up to 2011-01-01 23:59:59 UTC
|
179
|
+
visits.last.hourly.should == [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
|
180
|
+
end
|
181
|
+
|
182
|
+
it "Hours in Europe/Madrid (Summer time) should be shifted by 2 hour from UTC" do
|
183
|
+
ENV["TZ"] = "Europe/Madrid"
|
184
|
+
|
185
|
+
time = Time.parse("2011-06-01")
|
186
|
+
t1 = time.change(:hour => 1)
|
187
|
+
t2 = time.change(:hour => 22)
|
188
|
+
|
189
|
+
@mock.visits.inc(t1)
|
190
|
+
@mock.visits.inc(t2)
|
191
|
+
|
192
|
+
# This test is interesting. We added with local TZ time but want to
|
193
|
+
# query shifted data on UTC. We need to read the expected span dates
|
194
|
+
# separately
|
195
|
+
visits = @mock.visits.on(time.utc..(time.utc + 1.day))
|
196
|
+
|
197
|
+
# Data from 2011-05-31 00:00:00 UTC up to 2011-05-31 23:59:59 UTC
|
198
|
+
visits.first.hourly.should == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
199
|
+
|
200
|
+
# Data from 2011-06-01 00:00:00 UTC up to 2011-06-01 23:59:59 UTC
|
201
|
+
visits.last.hourly.should == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
|
202
|
+
end
|
203
|
+
|
204
|
+
it "Hours in America/Los_Angeles (Winter time) should be shifted by -8 hours from UTC" do
|
205
|
+
ENV["TZ"] = "America/Los_Angeles"
|
206
|
+
|
207
|
+
time = Time.parse("2011-01-01")
|
208
|
+
t1 = time.change(:hour => 1)
|
209
|
+
t2 = time.change(:hour => 22)
|
210
|
+
|
211
|
+
@mock.visits.inc(t1)
|
212
|
+
@mock.visits.inc(t2)
|
213
|
+
|
214
|
+
# This test is interesting. We added with local TZ time but want to
|
215
|
+
# query shifted data on UTC. We need to read the expected span dates
|
216
|
+
# separately
|
217
|
+
visits = @mock.visits.on(time.utc..(time.utc + 1.day))
|
218
|
+
|
219
|
+
# Data from 2011-01-01 00:00:00 UTC up to 2011-01-01 23:59:59 UTC
|
220
|
+
visits.first.hourly.should == [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
221
|
+
|
222
|
+
# Data from 2011-01-02 00:00:00 UTC up to 2011-01-02 23:59:59 UTC
|
223
|
+
visits.last.hourly.should == [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
224
|
+
end
|
225
|
+
|
226
|
+
it "Hours in America/Los_Angeles (Summer time) should be shifted by -7 hours from UTC" do
|
227
|
+
ENV["TZ"] = "America/Los_Angeles"
|
228
|
+
|
229
|
+
time = Time.parse("2011-06-01")
|
230
|
+
t1 = time.change(:hour => 1)
|
231
|
+
t2 = time.change(:hour => 22)
|
232
|
+
|
233
|
+
@mock.visits.inc(t1)
|
234
|
+
@mock.visits.inc(t2)
|
235
|
+
|
236
|
+
# This test is interesting. We added with local TZ time but want to
|
237
|
+
# query shifted data on UTC. We need to read the expected span dates
|
238
|
+
# separately
|
239
|
+
visits = @mock.visits.on(time.utc..(time.utc + 1.day))
|
240
|
+
|
241
|
+
# Data from 2011-01-01 00:00:00 UTC up to 2011-01-01 23:59:59 UTC
|
242
|
+
visits.first.hourly.should == [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
243
|
+
|
244
|
+
# Data from 2011-01-02 00:00:00 UTC up to 2011-01-02 23:59:59 UTC
|
245
|
+
visits.last.hourly.should == [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|
249
|
+
end
|
data/spec/trackoid_spec.rb
CHANGED
@@ -50,6 +50,10 @@ describe Mongoid::Tracking do
|
|
50
50
|
@mock.respond_to?(:visits).should be_true
|
51
51
|
end
|
52
52
|
|
53
|
+
it "should NOT create an index for the stats field" do
|
54
|
+
@mock.class.index_options.should_not include(:visits_data)
|
55
|
+
end
|
56
|
+
|
53
57
|
it "should respond 'false' to field_changed? method" do
|
54
58
|
# Ok, this test is not very relevant since it will return false even
|
55
59
|
# if Trackid does not override it.
|
@@ -105,6 +109,7 @@ describe Mongoid::Tracking do
|
|
105
109
|
|
106
110
|
before do
|
107
111
|
@mock = Test.find(@object_id)
|
112
|
+
@today = Time.now
|
108
113
|
end
|
109
114
|
|
110
115
|
it "should increment visits stats for today" do
|
@@ -118,12 +123,12 @@ describe Mongoid::Tracking do
|
|
118
123
|
end
|
119
124
|
|
120
125
|
it "should also work for yesterday" do
|
121
|
-
@mock.visits.inc(
|
126
|
+
@mock.visits.inc(@today - 1.day)
|
122
127
|
@mock.visits.yesterday.should == 1
|
123
128
|
end
|
124
129
|
|
125
130
|
it "should also work for yesterday if adding another visit (for a total of 2)" do
|
126
|
-
@mock.visits.inc(
|
131
|
+
@mock.visits.inc(@today - 1.day)
|
127
132
|
@mock.visits.yesterday.should == 2
|
128
133
|
end
|
129
134
|
|
@@ -145,11 +150,16 @@ describe Mongoid::Tracking do
|
|
145
150
|
end
|
146
151
|
|
147
152
|
it "should give the first date with first_date" do
|
148
|
-
|
153
|
+
t = Time.parse("2010-07-11")
|
154
|
+
f = @mock.visits.first_date
|
155
|
+
[f.year, f.month, f.day, f.hour].should == [t.year, t.month, t.day, t.hour]
|
149
156
|
end
|
150
157
|
|
151
158
|
it "should give the last date with last_date" do
|
152
|
-
@
|
159
|
+
future = @today + 1.month
|
160
|
+
@mock.visits.set(22, future)
|
161
|
+
f = @mock.visits.last_date
|
162
|
+
[f.year, f.month, f.day, f.hour].should == [future.year, future.month, future.day, future.hour]
|
153
163
|
end
|
154
164
|
|
155
165
|
it "should give the first value" do
|
@@ -157,7 +167,7 @@ describe Mongoid::Tracking do
|
|
157
167
|
end
|
158
168
|
|
159
169
|
it "should give the last value" do
|
160
|
-
@mock.visits.last_value.should ==
|
170
|
+
@mock.visits.last_value.should == 22
|
161
171
|
end
|
162
172
|
end
|
163
173
|
|
@@ -179,9 +189,9 @@ describe Mongoid::Tracking do
|
|
179
189
|
end
|
180
190
|
|
181
191
|
it "'set' operator must work on arbitrary days" do
|
182
|
-
@mock.visits.set(5,
|
183
|
-
@mock.visits.on(
|
184
|
-
Test.find(@object_id).visits.on(
|
192
|
+
@mock.visits.set(5, Time.parse("2010-05-01"))
|
193
|
+
@mock.visits.on(Time.parse("2010-05-01")).should == 5
|
194
|
+
Test.find(@object_id).visits.on(Time.parse("2010-05-01")).should == 5
|
185
195
|
end
|
186
196
|
|
187
197
|
it "'add' operator must work" do
|
@@ -191,9 +201,9 @@ describe Mongoid::Tracking do
|
|
191
201
|
end
|
192
202
|
|
193
203
|
it "'add' operator must work on arbitrary days" do
|
194
|
-
@mock.visits.add(5,
|
195
|
-
@mock.visits.on(
|
196
|
-
Test.find(@object_id).visits.on(
|
204
|
+
@mock.visits.add(5, Time.parse("2010-05-01"))
|
205
|
+
@mock.visits.on(Time.parse("2010-05-01")).should == 10
|
206
|
+
Test.find(@object_id).visits.on(Time.parse("2010-05-01")).should == 10
|
197
207
|
end
|
198
208
|
|
199
209
|
it "on() accessor must work on dates as String" do
|
@@ -201,14 +211,14 @@ describe Mongoid::Tracking do
|
|
201
211
|
@mock.visits.on("2010-05-01").should == 10
|
202
212
|
end
|
203
213
|
|
204
|
-
it "on() accessor must work on
|
214
|
+
it "on() accessor must work on Date descendants" do
|
205
215
|
# We have data for today as previous tests populated the visits field
|
206
216
|
@mock.visits.on(Date.parse("2010-05-01")).should == 10
|
207
217
|
end
|
208
218
|
|
209
219
|
it "on() accessor must work on dates as Ranges" do
|
210
220
|
# We have data for today as previous tests populated the visits field
|
211
|
-
@mock.visits.on(
|
221
|
+
@mock.visits.on(Time.parse("2010-04-30")..Time.parse("2010-05-02")).should == [0, 10, 0]
|
212
222
|
end
|
213
223
|
end
|
214
224
|
|