trackoid 0.3.8 → 0.4.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/.gitignore +22 -0
- data/Gemfile +5 -9
- data/{README.rdoc → README.md} +42 -34
- data/Rakefile +2 -40
- data/config/mongoid.yml +8 -0
- data/lib/{trackoid → mongoid}/tracking.rb +6 -25
- data/lib/{trackoid → mongoid/tracking}/aggregates.rb +17 -13
- data/lib/mongoid/tracking/core_ext.rb +3 -0
- data/lib/{trackoid → mongoid/tracking}/core_ext/range.rb +0 -0
- data/lib/{trackoid → mongoid/tracking}/core_ext/time.rb +2 -1
- data/lib/mongoid/tracking/errors.rb +40 -0
- data/lib/{trackoid → mongoid/tracking}/reader_extender.rb +0 -0
- data/lib/{trackoid → mongoid/tracking}/readers.rb +0 -0
- data/lib/{trackoid → mongoid/tracking}/tracker.rb +35 -46
- data/lib/{trackoid → mongoid/tracking}/tracker_aggregates.rb +2 -2
- data/lib/trackoid.rb +9 -19
- data/lib/trackoid/version.rb +5 -0
- data/spec/aggregates_spec.rb +132 -133
- data/spec/embedded_spec.rb +97 -0
- data/spec/spec_helper.rb +7 -17
- data/spec/trackoid_spec.rb +74 -78
- data/trackoid.gemspec +16 -69
- metadata +108 -113
- data/VERSION +0 -1
- data/lib/trackoid/core_ext.rb +0 -3
- data/lib/trackoid/errors.rb +0 -38
File without changes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc
|
3
|
+
module Tracking #:nodoc
|
4
|
+
module Errors #:nodoc
|
5
|
+
|
6
|
+
class ClassAlreadyDefined < RuntimeError
|
7
|
+
def initialize(klass)
|
8
|
+
@klass = klass
|
9
|
+
end
|
10
|
+
def message
|
11
|
+
"#{@klass} already defined, can't aggregate!"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class AggregationAlreadyDefined < RuntimeError
|
16
|
+
def initialize(klass, token)
|
17
|
+
@klass = klass
|
18
|
+
@token = token
|
19
|
+
end
|
20
|
+
def message
|
21
|
+
"Aggregation '#{@token}' already defined for model #{@klass}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class AggregationNameDeprecated < RuntimeError
|
26
|
+
def initialize(token)
|
27
|
+
@token = token
|
28
|
+
end
|
29
|
+
def message
|
30
|
+
"Ussing aggregation name '#{@klass}' is deprecated. Please select another name."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ModelNotSaved < RuntimeError; end
|
35
|
+
|
36
|
+
class NotMongoid < RuntimeError; end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
File without changes
|
File without changes
|
@@ -10,9 +10,7 @@ module Mongoid #:nodoc:
|
|
10
10
|
@owner, @for = owner, field
|
11
11
|
@for_data = @owner.internal_track_name(@for)
|
12
12
|
@data = @owner.read_attribute(@for_data)
|
13
|
-
|
14
|
-
# The following is needed if the "field" Mongoid definition for our
|
15
|
-
# internal tracking field does not include option ":default => {}"
|
13
|
+
|
16
14
|
if @data.nil?
|
17
15
|
@owner.write_attribute(@for_data, {})
|
18
16
|
@data = @owner.read_attribute(@for_data)
|
@@ -45,22 +43,17 @@ module Mongoid #:nodoc:
|
|
45
43
|
# read the actual value in return so that we save round trip delays.
|
46
44
|
#
|
47
45
|
update_data(data_for(date) + how_much, date)
|
48
|
-
@owner.
|
49
|
-
|
50
|
-
{ (how_much > 0 ? "$inc" : "$dec") => update_hash(how_much.abs, date) },
|
51
|
-
:upsert => true, :safe => false
|
52
|
-
)
|
46
|
+
@owner.inc(store_key(date), how_much.abs)
|
47
|
+
|
53
48
|
return unless @owner.aggregated?
|
54
49
|
|
55
|
-
@owner.aggregate_fields.each do |
|
50
|
+
@owner.aggregate_fields.each do |k, v|
|
56
51
|
next unless token = v.call(@aggregate_data)
|
57
52
|
fk = @owner.class.name.to_s.foreign_key.to_sym
|
58
|
-
selector = { fk => @owner.id, :
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
:upsert => true, :safe => false
|
63
|
-
)
|
53
|
+
selector = { fk => @owner.id, ns: k, key: token.to_s }
|
54
|
+
|
55
|
+
docs = @owner.aggregate_klass.collection.find(selector)
|
56
|
+
docs.upsert("$inc" => update_hash(how_much.abs, date))
|
64
57
|
end
|
65
58
|
end
|
66
59
|
|
@@ -75,20 +68,18 @@ module Mongoid #:nodoc:
|
|
75
68
|
def set(how_much, date = Time.now)
|
76
69
|
raise Errors::ModelNotSaved, "Can't update a new record" if @owner.new_record?
|
77
70
|
update_data(how_much, date)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
)
|
71
|
+
|
72
|
+
@owner.set(store_key(date), how_much)
|
73
|
+
|
82
74
|
return unless @owner.aggregated?
|
83
75
|
|
84
76
|
@owner.aggregate_fields.each do |(k,v)|
|
85
77
|
next unless token = v.call(@aggregate_data)
|
86
78
|
fk = @owner.class.name.to_s.foreign_key.to_sym
|
87
|
-
selector = { fk => @owner.id, :
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
)
|
79
|
+
selector = { fk => @owner.id, ns: k, key: token.to_s }
|
80
|
+
|
81
|
+
docs = @owner.aggregate_klass.collection.find(selector)
|
82
|
+
docs.upsert("$set" => update_hash(how_much.abs, date))
|
92
83
|
end
|
93
84
|
end
|
94
85
|
|
@@ -103,11 +94,9 @@ module Mongoid #:nodoc:
|
|
103
94
|
# operations over all mongo records for this aggregate field
|
104
95
|
@owner.aggregate_fields.each do |(k,v)|
|
105
96
|
fk = @owner.class.name.to_s.foreign_key.to_sym
|
106
|
-
selector = { fk => @owner.id, :
|
107
|
-
@owner.aggregate_klass.collection.
|
108
|
-
|
109
|
-
:upsert => true, :multi => true, :safe => false
|
110
|
-
)
|
97
|
+
selector = { fk => @owner.id, ns: k }
|
98
|
+
docs = @owner.aggregate_klass.collection.find(selector)
|
99
|
+
docs.update_all("$set" => update_hash(how_much.abs, date))
|
111
100
|
end
|
112
101
|
end
|
113
102
|
|
@@ -115,22 +104,19 @@ module Mongoid #:nodoc:
|
|
115
104
|
raise Errors::ModelNotSaved, "Can't update a new record" if @owner.new_record?
|
116
105
|
|
117
106
|
remove_data(date)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
:upsert => true, :safe => false
|
122
|
-
)
|
107
|
+
|
108
|
+
@owner.unset(store_key(date))
|
109
|
+
|
123
110
|
return unless @owner.aggregated?
|
124
111
|
|
125
112
|
# Need to iterate over all aggregates and send an update or delete
|
126
113
|
# operations over all mongo records
|
127
114
|
@owner.aggregate_fields.each do |(k,v)|
|
128
115
|
fk = @owner.class.name.to_s.foreign_key.to_sym
|
129
|
-
selector = { fk => @owner.id, :
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
)
|
116
|
+
selector = { fk => @owner.id, ns: k }
|
117
|
+
|
118
|
+
docs = @owner.aggregate_klass.collection.find(selector)
|
119
|
+
docs.update_all("$unset" => update_hash(1, date))
|
134
120
|
end
|
135
121
|
end
|
136
122
|
|
@@ -162,10 +148,10 @@ module Mongoid #:nodoc:
|
|
162
148
|
date = normalize_date(date)
|
163
149
|
if date.first.utc?
|
164
150
|
keys = date.map(&:to_key_timestamp)
|
165
|
-
keys.inject([])
|
151
|
+
keys.inject([]) do |r, e|
|
166
152
|
d = expand_hash(@data[e])
|
167
153
|
r << ReaderExtender.new(d.sum, d)
|
168
|
-
|
154
|
+
end
|
169
155
|
else
|
170
156
|
first = date.first.whole_day.first.to_key_timestamp
|
171
157
|
last = date.last.whole_day.last.to_key_timestamp
|
@@ -185,7 +171,7 @@ module Mongoid #:nodoc:
|
|
185
171
|
|
186
172
|
def expand_hash(h)
|
187
173
|
d = Array.new(24, 0)
|
188
|
-
h.inject(d) {|d,e| d[e.first.to_i] = e.last; d} if h
|
174
|
+
h.inject(d) { |d, e| d[e.first.to_i] = e.last; d } if h
|
189
175
|
d
|
190
176
|
end
|
191
177
|
|
@@ -214,13 +200,16 @@ module Mongoid #:nodoc:
|
|
214
200
|
end
|
215
201
|
end
|
216
202
|
|
203
|
+
# Returns a store key for passed date.
|
204
|
+
def store_key(date)
|
205
|
+
"#{@for_data}.#{normalize_date(date).to_key}"
|
206
|
+
end
|
207
|
+
|
217
208
|
def update_hash(num, date)
|
218
|
-
|
219
|
-
{
|
220
|
-
"#{@for_data}.#{date.to_key}" => num
|
221
|
-
}
|
209
|
+
{ store_key(date) => num }
|
222
210
|
end
|
223
211
|
|
212
|
+
# Allow for dates to be different types.
|
224
213
|
def normalize_date(date)
|
225
214
|
case date
|
226
215
|
when String
|
@@ -10,8 +10,8 @@ module Mongoid #:nodoc:
|
|
10
10
|
@track_field = track_field
|
11
11
|
|
12
12
|
@accessor = @owner.class.send(:internal_accessor_name, @token)
|
13
|
-
@selector = {:
|
14
|
-
@selector.merge!(:
|
13
|
+
@selector = { ns: @token }
|
14
|
+
@selector.merge!(key: @key) if @key
|
15
15
|
|
16
16
|
@criteria = @owner.send(@accessor).where(@selector)
|
17
17
|
end
|
data/lib/trackoid.rb
CHANGED
@@ -1,22 +1,12 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require 'rubygems'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
require 'trackoid/errors'
|
7
|
-
require 'trackoid/core_ext'
|
8
|
-
require 'trackoid/reader_extender'
|
9
|
-
require 'trackoid/readers'
|
10
|
-
require 'trackoid/tracker'
|
11
|
-
require 'trackoid/aggregates'
|
12
|
-
require 'trackoid/tracker_aggregates'
|
13
|
-
require 'trackoid/tracking'
|
14
|
-
|
15
|
-
module Mongoid #:nodoc:
|
16
|
-
module Tracking
|
17
|
-
|
18
|
-
VERSION = File.read(File.expand_path("../VERSION", File.dirname(__FILE__)))
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
3
|
+
require 'trackoid/version'
|
22
4
|
|
5
|
+
require 'mongoid/tracking'
|
6
|
+
require 'mongoid/tracking/errors'
|
7
|
+
require 'mongoid/tracking/core_ext'
|
8
|
+
require 'mongoid/tracking/reader_extender'
|
9
|
+
require 'mongoid/tracking/readers'
|
10
|
+
require 'mongoid/tracking/tracker'
|
11
|
+
require 'mongoid/tracking/aggregates'
|
12
|
+
require 'mongoid/tracking/tracker_aggregates'
|
data/spec/aggregates_spec.rb
CHANGED
@@ -25,7 +25,7 @@ class SecondTestModel
|
|
25
25
|
|
26
26
|
aggregate :aggregate_one do 1 end
|
27
27
|
aggregate :aggregate_two do "p" end
|
28
|
-
aggregate :aggregate_three do BSON::ObjectId
|
28
|
+
aggregate :aggregate_three do Moped::BSON::ObjectId.new end
|
29
29
|
aggregate :aggregate_four do Time.now end
|
30
30
|
end
|
31
31
|
|
@@ -109,7 +109,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
109
109
|
"(none)"
|
110
110
|
end
|
111
111
|
end
|
112
|
-
}.should raise_error Mongoid::Errors::AggregationAlreadyDefined
|
112
|
+
}.should raise_error Mongoid::Tracking::Errors::AggregationAlreadyDefined
|
113
113
|
end
|
114
114
|
|
115
115
|
it "should raise error if we try to use 'hours' as aggregate" do
|
@@ -119,7 +119,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
119
119
|
"(none)"
|
120
120
|
end
|
121
121
|
end
|
122
|
-
}.should raise_error Mongoid::Errors::AggregationNameDeprecated
|
122
|
+
}.should raise_error Mongoid::Tracking::Errors::AggregationNameDeprecated
|
123
123
|
end
|
124
124
|
|
125
125
|
it "should have Mongoid accessors defined" do
|
@@ -150,7 +150,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
150
150
|
"other"
|
151
151
|
end
|
152
152
|
end
|
153
|
-
}.should raise_error Mongoid::Errors::ClassAlreadyDefined
|
153
|
+
}.should raise_error Mongoid::Tracking::Errors::ClassAlreadyDefined
|
154
154
|
end
|
155
155
|
|
156
156
|
it "should NOT raise error if the already defined class is our aggregated model" do
|
@@ -168,7 +168,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
168
168
|
"other"
|
169
169
|
end
|
170
170
|
end
|
171
|
-
}.should_not raise_error Mongoid::Errors::ClassAlreadyDefined
|
171
|
+
}.should_not raise_error Mongoid::Tracking::Errors::ClassAlreadyDefined
|
172
172
|
end
|
173
173
|
|
174
174
|
it "should raise error although the already defined class includes tracking" do
|
@@ -186,161 +186,163 @@ describe Mongoid::Tracking::Aggregates do
|
|
186
186
|
"other"
|
187
187
|
end
|
188
188
|
end
|
189
|
-
}.should raise_error Mongoid::Errors::ClassAlreadyDefined
|
189
|
+
}.should raise_error Mongoid::Tracking::Errors::ClassAlreadyDefined
|
190
190
|
end
|
191
191
|
|
192
192
|
describe "testing different object class for aggregation key" do
|
193
|
-
|
194
|
-
SecondTestModel.
|
195
|
-
SecondTestModel.create(:name => "test")
|
196
|
-
@object_id = SecondTestModel.first.id
|
197
|
-
@mock = SecondTestModel.find(@object_id)
|
193
|
+
let(:second_test_model) do
|
194
|
+
SecondTestModel.create(name: "test")
|
198
195
|
end
|
199
196
|
|
200
197
|
it "should correctly save all aggregation keys as strings (inc)" do
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
198
|
+
second_test_model.something("test").inc
|
199
|
+
second_test_model.something.aggregate_one.first.key.is_a?(String).should be_true
|
200
|
+
second_test_model.something.aggregate_two.first.key.is_a?(String).should be_true
|
201
|
+
second_test_model.something.aggregate_three.first.key.is_a?(String).should be_true
|
202
|
+
second_test_model.something.aggregate_four.first.key.is_a?(String).should be_true
|
206
203
|
end
|
207
204
|
|
208
205
|
it "should correctly save all aggregation keys as strings (set)" do
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
206
|
+
second_test_model.something("test").set(5)
|
207
|
+
second_test_model.something.aggregate_one.first.key.is_a?(String).should be_true
|
208
|
+
second_test_model.something.aggregate_two.first.key.is_a?(String).should be_true
|
209
|
+
second_test_model.something.aggregate_three.first.key.is_a?(String).should be_true
|
210
|
+
second_test_model.something.aggregate_four.first.key.is_a?(String).should be_true
|
214
211
|
end
|
215
212
|
end
|
216
213
|
|
217
214
|
describe "when tracking a model with aggregation data" do
|
218
|
-
|
219
|
-
TestModel.all.map(&:destroy)
|
215
|
+
let(:test_model) do
|
220
216
|
TestModel.create(:name => "test")
|
221
|
-
@object_id = TestModel.first.id
|
222
|
-
end
|
223
|
-
|
224
|
-
before do
|
225
|
-
@mock = TestModel.find(@object_id)
|
226
217
|
end
|
227
218
|
|
228
219
|
it "calling an aggregation scope should return the appropiate class" do
|
229
|
-
|
220
|
+
test_model.browsers.class.should == Mongoid::Tracking::TrackerAggregates
|
230
221
|
end
|
231
222
|
|
232
223
|
it "should increment visits for all aggregated instances" do
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
224
|
+
test_model.visits("Mozilla Firefox").inc
|
225
|
+
test_model.browsers.count.should == 1
|
226
|
+
test_model.referers.count.should == 1
|
227
|
+
test_model.quarters.count.should == 1
|
237
228
|
end
|
238
229
|
|
239
230
|
it "should increment visits for specific aggregation keys" do
|
240
|
-
|
241
|
-
|
242
|
-
|
231
|
+
test_model.visits("Mozilla Firefox").inc
|
232
|
+
test_model.browsers("mozilla").size.should == 1
|
233
|
+
test_model.referers("firefox").size.should == 1
|
234
|
+
test_model.quarters("Q1").size.should == 1
|
243
235
|
end
|
244
236
|
|
245
237
|
it "should NOT increment visits for different aggregation keys" do
|
246
|
-
|
247
|
-
|
248
|
-
|
238
|
+
test_model.browsers("internet explorer").size.should == 0
|
239
|
+
test_model.referers("yahoo slurp").size.should == 0
|
240
|
+
test_model.quarters("Q2").size.should == 0
|
249
241
|
end
|
250
242
|
|
251
243
|
it "should have 1 visits today" do
|
252
|
-
|
253
|
-
|
244
|
+
test_model.visits("Mozilla Firefox").inc
|
245
|
+
test_model.visits.browsers.today.should == [["mozilla", 1]]
|
246
|
+
test_model.visits.referers.today.should == [["firefox", 1]]
|
254
247
|
end
|
255
248
|
|
256
249
|
it "should have 0 visits yesterday" do
|
257
|
-
|
258
|
-
|
250
|
+
test_model.visits("Mozilla Firefox").inc
|
251
|
+
test_model.visits.browsers.yesterday.should == [["mozilla", 0]]
|
252
|
+
test_model.visits.referers.yesterday.should == [["firefox", 0]]
|
259
253
|
end
|
260
254
|
|
261
255
|
it "should have 1 visits last 7 days" do
|
262
|
-
|
263
|
-
|
256
|
+
test_model.visits("Mozilla Firefox").inc
|
257
|
+
test_model.visits.browsers.last_days(7).should == [["mozilla", [0, 0, 0, 0, 0, 0, 1]]]
|
258
|
+
test_model.visits.referers.last_days(7).should == [["firefox", [0, 0, 0, 0, 0, 0, 1]]]
|
264
259
|
end
|
265
260
|
|
266
261
|
it "should work also for arbitrary days" do
|
267
|
-
|
268
|
-
|
262
|
+
test_model.visits("Mozilla Firefox").inc
|
263
|
+
test_model.visits.browsers.last_days(15).should == [["mozilla", [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]]
|
264
|
+
test_model.visits.referers.last_days(15).should == [["firefox", [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]]
|
269
265
|
end
|
270
266
|
|
271
267
|
it "should work adding 1 visit with different aggregation data" do
|
272
|
-
|
273
|
-
|
274
|
-
|
268
|
+
test_model.visits("Mozilla Firefox").inc
|
269
|
+
test_model.visits("Google Chrome").inc
|
270
|
+
test_model.visits.browsers.today.should =~ [["mozilla", 1], ["google", 1]]
|
271
|
+
test_model.visits.referers.today.should =~ [["firefox", 1], ["chrome", 1]]
|
275
272
|
|
276
273
|
# Just for testing array manipulations
|
277
|
-
|
274
|
+
test_model.visits.browsers.today.inject(0) {|total, c| total + c.last }.should == 2
|
278
275
|
end
|
279
276
|
|
280
277
|
it "should return only values when specifying the aggregation key" do
|
281
|
-
|
278
|
+
test_model.visits("Mozilla Firefox").inc
|
279
|
+
test_model.visits.browsers("mozilla").today.should == 1
|
282
280
|
end
|
283
281
|
|
284
282
|
it "should work also with set" do
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
283
|
+
test_model.visits("Mozilla Firefox").inc
|
284
|
+
test_model.visits("Google Chrome").set(5)
|
285
|
+
test_model.visits.browsers.today.should =~ [["mozilla", 1], ["google", 5]]
|
286
|
+
test_model.visits.referers.today.should =~ [["firefox", 1], ["chrome", 5]]
|
287
|
+
test_model.visits.today.should == 5
|
289
288
|
end
|
290
289
|
|
291
290
|
it "let's check what happens when sorting the best browser..." do
|
292
|
-
|
293
|
-
|
294
|
-
|
291
|
+
test_model.visits("Mozilla Firefox").inc
|
292
|
+
test_model.visits("Google Chrome").set(6)
|
293
|
+
test_model.visits.browsers.today.should =~ [["mozilla", 1], ["google", 6]]
|
294
|
+
test_model.visits.browsers.today.max {|a,b| a.second <=> b.second }.should == ["google", 6]
|
295
295
|
end
|
296
296
|
|
297
297
|
it "should work without aggregation information" do
|
298
|
-
|
299
|
-
|
300
|
-
|
298
|
+
test_model.visits("Mozilla Firefox").set(1)
|
299
|
+
test_model.visits("Google Chrome").set(6)
|
300
|
+
test_model.visits.inc
|
301
|
+
|
302
|
+
|
303
|
+
test_model.visits.browsers.today.should =~ [["mozilla", 1], ["google", 6]]
|
304
|
+
test_model.visits.referers.today.should =~ [["firefox", 1], ["chrome", 6]]
|
301
305
|
|
302
306
|
# A more throughout test would check totals...
|
303
|
-
visits_today =
|
304
|
-
visits_today_with_browser =
|
307
|
+
visits_today = test_model.visits.today
|
308
|
+
visits_today_with_browser = test_model.visits.browsers.today.inject(0) {|total, c| total + c.last }
|
305
309
|
visits_today.should == visits_today_with_browser
|
306
310
|
end
|
307
311
|
end
|
308
312
|
|
309
313
|
describe "When using reset method for aggregates" do
|
310
|
-
|
311
|
-
TestModel.all.map(&:destroy)
|
314
|
+
let(:test_model) do
|
312
315
|
TestModel.create(:name => "test")
|
316
|
+
end
|
313
317
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
@mock.visits("Google Chrome").set(2, "2010-07-11")
|
319
|
-
@mock.visits("Internet Explorer").set(3, "2010-07-11")
|
318
|
+
before(:each) do
|
319
|
+
test_model.visits("Mozilla Firefox").set(1, "2010-07-11")
|
320
|
+
test_model.visits("Google Chrome").set(2, "2010-07-11")
|
321
|
+
test_model.visits("Internet Explorer").set(3, "2010-07-11")
|
320
322
|
|
321
|
-
|
322
|
-
|
323
|
-
|
323
|
+
test_model.visits("Mozilla Firefox").set(4, "2010-07-14")
|
324
|
+
test_model.visits("Google Chrome").set(5, "2010-07-14")
|
325
|
+
test_model.visits("Internet Explorer").set(6, "2010-07-14")
|
324
326
|
|
325
|
-
|
326
|
-
|
327
|
-
|
327
|
+
test_model.uniques("Mozilla Firefox").set(1, "2010-07-11")
|
328
|
+
test_model.uniques("Google Chrome").set(2, "2010-07-11")
|
329
|
+
test_model.uniques("Internet Explorer").set(3, "2010-07-11")
|
328
330
|
|
329
|
-
|
330
|
-
|
331
|
-
|
331
|
+
test_model.uniques("Mozilla Firefox").set(4, "2010-07-14")
|
332
|
+
test_model.uniques("Google Chrome").set(5, "2010-07-14")
|
333
|
+
test_model.uniques("Internet Explorer").set(6, "2010-07-14")
|
332
334
|
end
|
333
335
|
|
334
336
|
it "should have the correct values when using a value" do
|
335
|
-
|
337
|
+
test_model.visits.reset(99, "2010-07-14")
|
336
338
|
|
337
|
-
|
338
|
-
|
339
|
+
test_model.visits.on("2010-07-14").should == 99
|
340
|
+
test_model.visits.browsers.all_values.should =~ [
|
339
341
|
["mozilla", [1, 0, 0, 99]],
|
340
342
|
["google", [2, 0, 0, 99]],
|
341
343
|
["internet", [3, 0, 0, 99]]
|
342
344
|
]
|
343
|
-
|
345
|
+
test_model.visits.referers.all_values.should =~ [
|
344
346
|
["firefox", [1, 0, 0, 99]],
|
345
347
|
["chrome", [2, 0, 0, 99]],
|
346
348
|
["explorer", [3, 0, 0, 99]]
|
@@ -348,14 +350,14 @@ describe Mongoid::Tracking::Aggregates do
|
|
348
350
|
end
|
349
351
|
|
350
352
|
it "should delete the values when using nil" do
|
351
|
-
|
352
|
-
|
353
|
-
|
353
|
+
test_model.visits.reset(nil, "2010-07-14")
|
354
|
+
test_model.visits.on("2010-07-14").should == 0
|
355
|
+
test_model.visits.browsers.all_values.should =~ [
|
354
356
|
["mozilla", [1]],
|
355
357
|
["google", [2]],
|
356
358
|
["internet", [3]]
|
357
359
|
]
|
358
|
-
|
360
|
+
test_model.visits.referers.all_values.should =~ [
|
359
361
|
["firefox", [1]],
|
360
362
|
["chrome", [2]],
|
361
363
|
["explorer", [3]]
|
@@ -363,10 +365,10 @@ describe Mongoid::Tracking::Aggregates do
|
|
363
365
|
end
|
364
366
|
|
365
367
|
it "erase method sould also work" do
|
366
|
-
|
368
|
+
test_model.visits.erase("2010-07-14")
|
367
369
|
|
368
|
-
|
369
|
-
|
370
|
+
test_model.visits.on("2010-07-14").should == 0
|
371
|
+
test_model.visits.browsers.all_values.should =~ [
|
370
372
|
["mozilla", [1]],
|
371
373
|
["google", [2]],
|
372
374
|
["internet", [3]]
|
@@ -374,15 +376,15 @@ describe Mongoid::Tracking::Aggregates do
|
|
374
376
|
end
|
375
377
|
|
376
378
|
it "should reset the correct tracking fields" do
|
377
|
-
|
379
|
+
test_model.visits.reset(99, "2010-07-14")
|
378
380
|
|
379
|
-
|
380
|
-
|
381
|
+
test_model.uniques.on("2010-07-14").should == 6
|
382
|
+
test_model.uniques.browsers.all_values.should =~ [
|
381
383
|
["mozilla", [1, 0, 0, 4]],
|
382
384
|
["google", [2, 0, 0, 5]],
|
383
385
|
["internet", [3, 0, 0, 6]]
|
384
386
|
]
|
385
|
-
|
387
|
+
test_model.uniques.referers.all_values.should =~ [
|
386
388
|
["firefox", [1, 0, 0, 4]],
|
387
389
|
["chrome", [2, 0, 0, 5]],
|
388
390
|
["explorer", [3, 0, 0, 6]]
|
@@ -390,15 +392,15 @@ describe Mongoid::Tracking::Aggregates do
|
|
390
392
|
end
|
391
393
|
|
392
394
|
it "should erase the correct tracking fields" do
|
393
|
-
|
395
|
+
test_model.visits.erase("2010-07-14")
|
394
396
|
|
395
|
-
|
396
|
-
|
397
|
+
test_model.uniques.on("2010-07-14").should == 6
|
398
|
+
test_model.uniques.browsers.all_values.should =~ [
|
397
399
|
["mozilla", [1, 0, 0, 4]],
|
398
400
|
["google", [2, 0, 0, 5]],
|
399
401
|
["internet", [3, 0, 0, 6]]
|
400
402
|
]
|
401
|
-
|
403
|
+
test_model.uniques.referers.all_values.should =~ [
|
402
404
|
["firefox", [1, 0, 0, 4]],
|
403
405
|
["chrome", [2, 0, 0, 5]],
|
404
406
|
["explorer", [3, 0, 0, 6]]
|
@@ -407,29 +409,26 @@ describe Mongoid::Tracking::Aggregates do
|
|
407
409
|
end
|
408
410
|
|
409
411
|
describe "Testing all accessors" do
|
410
|
-
|
411
|
-
TestModel.all.map(&:destroy)
|
412
|
-
TestModel.create(:name => "test")
|
413
|
-
@object_id = TestModel.first.id
|
414
|
-
@mock = TestModel.first
|
412
|
+
let(:test_model) { TestModel.create(name: "test") }
|
415
413
|
|
414
|
+
before do
|
416
415
|
# For 'first' values
|
417
|
-
|
418
|
-
|
419
|
-
|
416
|
+
test_model.visits("Mozilla Firefox").set(1, "2010-07-11")
|
417
|
+
test_model.visits("Google Chrome").set(2, "2010-07-12")
|
418
|
+
test_model.visits("Internet Explorer").set(3, "2010-07-13")
|
420
419
|
|
421
420
|
# For 'last' values
|
422
|
-
|
423
|
-
|
424
|
-
|
421
|
+
test_model.visits("Mozilla Firefox").set(4, "2010-07-14")
|
422
|
+
test_model.visits("Google Chrome").set(5, "2010-07-15")
|
423
|
+
test_model.visits("Internet Explorer").set(6, "2010-07-16")
|
425
424
|
end
|
426
425
|
|
427
426
|
it "should return the correct values for .all_values" do
|
428
|
-
|
427
|
+
test_model.visits.all_values.should == [1, 2, 3, 4, 5, 6]
|
429
428
|
end
|
430
429
|
|
431
430
|
it "should return the all values for every aggregate" do
|
432
|
-
|
431
|
+
test_model.visits.browsers.all_values.should =~ [
|
433
432
|
["mozilla", [1, 0, 0, 4]],
|
434
433
|
["google", [2, 0, 0, 5]],
|
435
434
|
["internet", [3, 0, 0, 6]]
|
@@ -437,7 +436,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
437
436
|
end
|
438
437
|
|
439
438
|
it "should return the correct first_date for every aggregate" do
|
440
|
-
|
439
|
+
test_model.visits.browsers.first_date.should =~ [
|
441
440
|
["mozilla", Time.parse("2010-07-11")],
|
442
441
|
["google", Time.parse("2010-07-12")],
|
443
442
|
["internet", Time.parse("2010-07-13")]
|
@@ -445,7 +444,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
445
444
|
end
|
446
445
|
|
447
446
|
it "should return the correct last_date for every aggregate" do
|
448
|
-
|
447
|
+
test_model.visits.browsers.last_date.should =~ [
|
449
448
|
["mozilla", Time.parse("2010-07-14")],
|
450
449
|
["google", Time.parse("2010-07-15")],
|
451
450
|
["internet", Time.parse("2010-07-16")]
|
@@ -453,7 +452,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
453
452
|
end
|
454
453
|
|
455
454
|
it "should return the first value for aggregates" do
|
456
|
-
|
455
|
+
test_model.visits.browsers.first_value.should =~ [
|
457
456
|
["mozilla", 1],
|
458
457
|
["google", 2],
|
459
458
|
["internet", 3]
|
@@ -461,7 +460,7 @@ describe Mongoid::Tracking::Aggregates do
|
|
461
460
|
end
|
462
461
|
|
463
462
|
it "should return the last value for aggregates" do
|
464
|
-
|
463
|
+
test_model.visits.browsers.last_value.should =~ [
|
465
464
|
["mozilla", 4],
|
466
465
|
["google", 5],
|
467
466
|
["internet", 6]
|
@@ -470,29 +469,29 @@ describe Mongoid::Tracking::Aggregates do
|
|
470
469
|
end
|
471
470
|
|
472
471
|
describe "When using models with same name on different namespaces" do
|
473
|
-
|
474
|
-
MyCompany::TestPerson.
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
472
|
+
let(:test_person1) do
|
473
|
+
MyCompany::TestPerson.create(my_name: "twoixter")
|
474
|
+
end
|
475
|
+
|
476
|
+
let(:test_person2) do
|
477
|
+
YourCompany::TestPerson.create(your_name: "test")
|
478
|
+
end
|
480
479
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
480
|
+
before do
|
481
|
+
test_person1.logins("ASCII").set(1, "2012-07-07")
|
482
|
+
test_person1.logins("EBCDIC").set(1, "2012-07-07")
|
483
|
+
|
484
|
+
test_person2.logins("UTF8").set(1, "2012-07-07")
|
485
|
+
test_person2.logins("LATIN1").set(1, "2012-07-07")
|
487
486
|
end
|
488
487
|
|
489
488
|
it "should be different objects" do
|
490
|
-
|
489
|
+
test_person1.my_name.should_not == test_person2.your_name
|
491
490
|
end
|
492
491
|
|
493
492
|
it "should yield different aggregates" do
|
494
|
-
|
495
|
-
|
493
|
+
test_person1.logins.initials.on("2012-07-07").should =~ [["A", 1], ["E", 1]]
|
494
|
+
test_person2.logins.initials.on("2012-07-07").should =~ [["U", 1], ["L", 1]]
|
496
495
|
end
|
497
496
|
end
|
498
497
|
end
|