trackoid 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|