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.
@@ -0,0 +1,97 @@
1
+ #
2
+ # This is a simple spec to check if tracking works within embedded documents
3
+ # If this passes, the rest of the funcionality it's assumed to work (TZ, etc)
4
+ #
5
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
6
+
7
+ class TestEmbedOne
8
+ include Mongoid::Document
9
+ field :name # Dummy field
10
+ embeds_one :embedded_test
11
+ end
12
+
13
+ class TestEmbedMany
14
+ include Mongoid::Document
15
+ field :name # Dummy field
16
+ embeds_many :embedded_test
17
+ end
18
+
19
+ class EmbeddedTest
20
+ include Mongoid::Document
21
+ include Mongoid::Tracking
22
+ field :name # Dummy field
23
+ track :visits
24
+ embedded_in :test_embed_one
25
+ embedded_in :test_embed_many
26
+ end
27
+
28
+ # And Now For Something Completely Different...
29
+
30
+ class TestEmbedOuter
31
+ include Mongoid::Document
32
+ field :name # Dummy field
33
+ embeds_one :test_embed_middle
34
+ end
35
+
36
+ class TestEmbedMiddle
37
+ include Mongoid::Document
38
+ field :name # Dummy field
39
+ embedded_in :test_embed_outer
40
+ embeds_one :test_embed_final
41
+ end
42
+
43
+ class TestEmbedFinal
44
+ include Mongoid::Document
45
+ include Mongoid::Tracking
46
+ field :name # Dummy field
47
+ track :visits
48
+ embedded_in :test_embed_middle
49
+ end
50
+
51
+
52
+ describe Mongoid::Tracking do
53
+
54
+ # Useful to see all MongoDB operations in place while RSpec is working
55
+ before(:all) do
56
+ # Moped.logger.level = Logger::DEBUG
57
+ end
58
+
59
+ context "within a document which embeds one or more models with tracking" do
60
+ let(:today) { Time.now }
61
+ let(:mock_one) { TestEmbedOne.create(:name => "Parent", :embedded_test => {:name => "Child"}) }
62
+ let(:mock_many) { TestEmbedMany.create(:name => "Parent", :embedded_test => [{:name => "Child1"}, {:name => "Child2"} ]) }
63
+
64
+ it "should have the tracking field working and not bleed to the parent" do
65
+ mock_one.respond_to?(:visits).should be_false
66
+ mock_one.embedded_test.respond_to?(:visits).should be_true
67
+
68
+ mock_many.respond_to?(:visits).should be_false
69
+ mock_many.embedded_test.first.respond_to?(:visits).should be_true
70
+ mock_many.embedded_test.last.respond_to?(:visits).should be_true
71
+ end
72
+
73
+ it "the tracking data should work fine" do
74
+ mock_one.embedded_test.visits.inc(today)
75
+ mock_one.embedded_test.visits.on(today).should == 1
76
+
77
+ mock_many.embedded_test.first.visits.inc(today)
78
+ mock_many.embedded_test.first.visits.on(today).should == 1
79
+ mock_many.embedded_test.last.visits.on(today).should == 0
80
+ end
81
+ end
82
+
83
+ context "within a three level embedded model" do
84
+ let(:today) { Time.now }
85
+ let(:outer) { TestEmbedOuter.create(:name => "Outer", :test_embed_middle => {:name => "Middle", :test_embed_final => { :name => "Final" }}) }
86
+
87
+ it "should just work..." do
88
+ outer.respond_to?(:visits).should be_false
89
+ outer.test_embed_middle.respond_to?(:visits).should be_false
90
+ outer.test_embed_middle.test_embed_final.respond_to?(:visits).should be_true
91
+
92
+ outer.test_embed_middle.test_embed_final.visits.inc(today)
93
+ outer.test_embed_middle.test_embed_final.visits.on(today).should == 1
94
+ outer.test_embed_middle.test_embed_final.visits.on(today - 1.day).should == 0
95
+ end
96
+ end
97
+ end
@@ -1,28 +1,18 @@
1
+ # FIXME: We should modify the load path here.
1
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
- require 'rubygems'
4
4
 
5
- # What is this doing here?
6
- # gem 'mocha', '>= 0.9.8'
7
-
8
- require 'mocha'
9
5
  require 'mongoid'
10
6
  require 'trackoid'
11
- require 'bson'
12
7
  require 'rspec'
13
8
  require 'rspec/autorun'
14
9
 
15
- Mongoid.configure do |config|
16
- name = "trackoid_test"
17
- host = "localhost"
18
- port = "27017"
19
- # config.master = Mongo::Connection.new(host, port, :logger => Logger.new(STDOUT)).db(name)
20
- config.master = Mongo::Connection.new.db(name)
21
- end
22
-
23
10
  RSpec.configure do |config|
24
- config.mock_with :mocha
25
- config.before :suite do
26
- Mongoid.master.collections.reject { |c| c.name =~ /^system\./ }.each(&:drop)
11
+ config.before(:suite) do
12
+ Mongoid.load!(File.expand_path(File.dirname(__FILE__) + "/../config/mongoid.yml"), :test)
13
+ end
14
+
15
+ config.after(:each) do
16
+ Mongoid::Config.purge!
27
17
  end
28
18
  end
@@ -9,25 +9,21 @@ class Test
9
9
  end
10
10
 
11
11
  describe Mongoid::Tracking do
12
- before(:all) do
13
- @trackoid_version = File.read(File.expand_path("../VERSION", File.dirname(__FILE__)))
12
+ it "should ensure allow_dynamic_fields option is turned off" do
13
+ Mongoid::Config.settings[:allow_dynamic_fields].should == false
14
14
  end
15
15
 
16
- it "should expose the same version as the VERSION file" do
17
- Mongoid::Tracking::VERSION.should == @trackoid_version
18
- end
19
-
20
16
  it "should raise error when used in a class not of class Mongoid::Document" do
21
- lambda {
17
+ -> {
22
18
  class NotMongoidClass
23
19
  include Mongoid::Tracking
24
20
  track :something
25
21
  end
26
- }.should raise_error Mongoid::Errors::NotMongoid
22
+ }.should raise_error Mongoid::Tracking::Errors::NotMongoid
27
23
  end
28
24
 
29
25
  it "should not raise error when used in a class of class Mongoid::Document" do
30
- lambda {
26
+ -> {
31
27
  class MongoidedDocument
32
28
  include Mongoid::Document
33
29
  include Mongoid::Tracking
@@ -37,13 +33,13 @@ describe Mongoid::Tracking do
37
33
  end
38
34
 
39
35
  it "should not raise errors when using to/as_json" do
40
- mock = Test.new(:name => "Trackoid")
36
+ test = Test.new(:name => "Trackoid")
41
37
  json_as = {}
42
38
  json_to = ""
43
39
 
44
- lambda {
45
- json_as = mock.as_json(:except => :_id)
46
- json_to = mock.to_json(:except => :_id)
40
+ -> {
41
+ json_as = test.as_json(:except => :_id)
42
+ json_to = test.to_json(:except => :_id)
47
43
  }.should_not raise_error
48
44
 
49
45
  json_as.should == { "name" => "Trackoid" }
@@ -55,11 +51,6 @@ describe Mongoid::Tracking do
55
51
  @mock = Test.new
56
52
  end
57
53
 
58
- it "should deny access to the underlying mongoid field" do
59
- lambda { @mock.visits_data }.should raise_error NoMethodError
60
- lambda { @mock.visits_data = {} }.should raise_error NoMethodError
61
- end
62
-
63
54
  it "should create a method for accesing the stats" do
64
55
  @mock.respond_to?(:visits).should be_true
65
56
  end
@@ -68,12 +59,6 @@ describe Mongoid::Tracking do
68
59
  @mock.class.index_options.should_not include(:visits_data)
69
60
  end
70
61
 
71
- it "should respond 'false' to field_changed? method" do
72
- # Ok, this test is not very relevant since it will return false even
73
- # if Trackoid does not override it.
74
- @mock.visits_changed?.should be_false
75
- end
76
-
77
62
  it "should create a method for accesing the stats of the proper class" do
78
63
  @mock.visits.class.should == Mongoid::Tracking::Tracker
79
64
  end
@@ -90,7 +75,7 @@ describe Mongoid::Tracking do
90
75
  end
91
76
 
92
77
  it "should not update stats when new record" do
93
- lambda { @mock.visits.inc }.should raise_error Mongoid::Errors::ModelNotSaved
78
+ -> { @mock.visits.inc }.should raise_error Mongoid::Tracking::Errors::ModelNotSaved
94
79
  end
95
80
 
96
81
  it "should create an empty hash as the internal representation" do
@@ -113,126 +98,137 @@ describe Mongoid::Tracking do
113
98
  @mock.aggregated?.should be_false
114
99
  end
115
100
  end
116
-
101
+
117
102
  describe "when using a model in the database" do
118
- before(:all) do
119
- Test.delete_all
120
- Test.create(:name => "test")
121
- @object_id = Test.first.id
122
- end
103
+ let(:test) { Test.create(:name => "test") }
123
104
 
124
105
  before do
125
- @mock = Test.find(@object_id)
126
106
  @today = Time.now
127
107
  end
128
108
 
129
109
  it "should increment visits stats for today" do
130
- @mock.visits.inc
131
- @mock.visits.today.should == 1
110
+ test.visits.inc
111
+ test.visits.today.should == 1
132
112
  end
133
113
 
134
114
  it "should increment another visits stats for today for a total of 2" do
135
- @mock.visits.inc
136
- @mock.visits.today.should == 2
115
+ test.visits.inc
116
+ test.visits.inc
117
+ test.visits.today.should == 2
137
118
  end
138
119
 
139
120
  it "should also work for yesterday" do
140
- @mock.visits.inc(@today - 1.day)
141
- @mock.visits.yesterday.should == 1
121
+ test.visits.inc(@today - 1.day)
122
+ test.visits.yesterday.should == 1
142
123
  end
143
124
 
144
125
  it "should also work for yesterday if adding another visit (for a total of 2)" do
145
- @mock.visits.inc(@today - 1.day)
146
- @mock.visits.yesterday.should == 2
126
+ test.visits.inc(@today - 1.day)
127
+ test.visits.inc(@today - 1.day)
128
+ test.visits.yesterday.should == 2
147
129
  end
148
-
130
+
149
131
  it "then, the visits of today + yesterday must be the same" do
150
- @mock.visits.last_days(2).should == [2, 2]
132
+ test.visits.inc
133
+ test.visits.inc
134
+ test.visits.inc(@today - 1.day)
135
+ test.visits.inc(@today - 1.day)
136
+ test.visits.last_days(2).should == [2, 2]
151
137
  end
152
138
 
153
139
  it "should have 4 visits for this test" do
154
- @mock.visits.last_days(2).sum.should == 4
140
+ test.visits.inc
141
+ test.visits.inc
142
+ test.visits.inc(@today - 1.day)
143
+ test.visits.inc(@today - 1.day)
144
+ test.visits.last_days(2).sum.should == 4
155
145
  end
156
146
 
157
147
  it "should correctly handle the 7 days" do
158
- @mock.visits.last_days.should == [0, 0, 0, 0, 0, 2, 2]
148
+ test.visits.inc
149
+ test.visits.inc
150
+ test.visits.inc(@today - 1.day)
151
+ test.visits.inc(@today - 1.day)
152
+ test.visits.last_days.should == [0, 0, 0, 0, 0, 2, 2]
159
153
  end
160
154
 
161
155
  it "string dates should work" do
162
- @mock.visits.inc("2010-07-11")
163
- @mock.visits.on("2010-07-11").should == 1
156
+ test.visits.inc("2010-07-11")
157
+ test.visits.on("2010-07-11").should == 1
164
158
  end
165
159
 
166
160
  it "should give the first date with first_date" do
161
+ test.visits.inc("2010-07-11")
167
162
  t = Time.parse("2010-07-11")
168
- f = @mock.visits.first_date
163
+ f = test.visits.first_date
169
164
  [f.year, f.month, f.day, f.hour].should == [t.year, t.month, t.day, t.hour]
170
165
  end
171
166
 
172
167
  it "should give the last date with last_date" do
173
168
  future = @today + 1.month
174
- @mock.visits.set(22, future)
175
- f = @mock.visits.last_date
169
+ test.visits.set(22, future)
170
+ f = test.visits.last_date
176
171
  [f.year, f.month, f.day, f.hour].should == [future.year, future.month, future.day, future.hour]
177
172
  end
178
173
 
179
174
  it "should give the first value" do
180
- @mock.visits.first_value.should == 1
175
+ test.visits.inc("2010-07-11")
176
+ test.visits.first_value.should == 1
181
177
  end
182
178
 
183
179
  it "should give the last value" do
184
- @mock.visits.last_value.should == 22
180
+ future = @today + 1.month
181
+ test.visits.set(22, future)
182
+ test.visits.last_value.should == 22
185
183
  end
186
184
  end
187
185
 
188
186
  context "testing reader operations without reloading models" do
189
- before(:all) do
190
- Test.delete_all
191
- Test.create(:name => "test")
192
- @object_id = Test.first.id
193
- end
194
-
195
- before do
196
- @mock = Test.find(@object_id)
197
- end
187
+ let(:test) { Test.create(name: "test") }
188
+ let(:object_id) { test.id }
198
189
 
199
190
  it "'set' operator must work" do
200
- @mock.visits.set(5)
201
- @mock.visits.today.should == 5
202
- Test.find(@object_id).visits.today.should == 5
191
+ test.visits.set(5)
192
+ test.visits.today.should == 5
193
+ Test.find(object_id).visits.today.should == 5
203
194
  end
204
195
 
205
196
  it "'set' operator must work on arbitrary days" do
206
- @mock.visits.set(5, Time.parse("2010-05-01"))
207
- @mock.visits.on(Time.parse("2010-05-01")).should == 5
208
- Test.find(@object_id).visits.on(Time.parse("2010-05-01")).should == 5
197
+ test.visits.set(5, Time.parse("2010-05-01"))
198
+ test.visits.on(Time.parse("2010-05-01")).should == 5
199
+ Test.find(object_id).visits.on(Time.parse("2010-05-01")).should == 5
209
200
  end
210
201
 
211
202
  it "'add' operator must work" do
212
- @mock.visits.add(5)
213
- @mock.visits.today.should == 10 # Remember 5 set on previous test
214
- Test.find(@object_id).visits.today.should == 10
203
+ test.visits.set(5)
204
+ test.visits.add(5)
205
+ test.visits.today.should == 10
206
+ Test.find(object_id).visits.today.should == 10
215
207
  end
216
208
 
217
209
  it "'add' operator must work on arbitrary days" do
218
- @mock.visits.add(5, Time.parse("2010-05-01"))
219
- @mock.visits.on(Time.parse("2010-05-01")).should == 10
220
- Test.find(@object_id).visits.on(Time.parse("2010-05-01")).should == 10
210
+ test.visits.set(5, Time.parse("2010-05-01"))
211
+ test.visits.add(5, Time.parse("2010-05-01"))
212
+ test.visits.on(Time.parse("2010-05-01")).should == 10
213
+ Test.find(object_id).visits.on(Time.parse("2010-05-01")).should == 10
221
214
  end
222
215
 
223
216
  it "on() accessor must work on dates as String" do
224
- # We have data for today as previous tests populated the visits field
225
- @mock.visits.on("2010-05-01").should == 10
217
+ test.visits.set(5, Time.parse("2010-05-01"))
218
+ test.visits.add(5, Time.parse("2010-05-01"))
219
+ test.visits.on("2010-05-01").should == 10
226
220
  end
227
221
 
228
222
  it "on() accessor must work on Date descendants" do
229
- # We have data for today as previous tests populated the visits field
230
- @mock.visits.on(Date.parse("2010-05-01")).should == 10
223
+ test.visits.set(5, Time.parse("2010-05-01"))
224
+ test.visits.add(5, Time.parse("2010-05-01"))
225
+ test.visits.on(Date.parse("2010-05-01")).should == 10
231
226
  end
232
227
 
233
228
  it "on() accessor must work on dates as Ranges" do
234
- # We have data for today as previous tests populated the visits field
235
- @mock.visits.on(Time.parse("2010-04-30")..Time.parse("2010-05-02")).should == [0, 10, 0]
229
+ test.visits.set(5, Time.parse("2010-05-01"))
230
+ test.visits.add(5, Time.parse("2010-05-01"))
231
+ test.visits.on(Time.parse("2010-04-30")..Time.parse("2010-05-02")).should == [0, 10, 0]
236
232
  end
237
233
  end
238
234
 
@@ -1,78 +1,25 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "trackoid/version"
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "trackoid"
8
- s.version = "0.3.8"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.version = Trackoid::VERSION
9
+ s.platform = Gem::Platform::RUBY
11
10
  s.authors = ["Jose Miguel Perez"]
12
- s.date = "2012-07-07"
13
- s.description = "Trackoid uses an embeddable approach to track analytics data using the poweful features of MongoDB for scalability"
14
11
  s.email = "josemiguel@perezruiz.com"
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".document",
21
- ".rspec",
22
- "Gemfile",
23
- "LICENSE",
24
- "README.rdoc",
25
- "Rakefile",
26
- "VERSION",
27
- "lib/trackoid.rb",
28
- "lib/trackoid/aggregates.rb",
29
- "lib/trackoid/core_ext.rb",
30
- "lib/trackoid/core_ext/range.rb",
31
- "lib/trackoid/core_ext/time.rb",
32
- "lib/trackoid/errors.rb",
33
- "lib/trackoid/reader_extender.rb",
34
- "lib/trackoid/readers.rb",
35
- "lib/trackoid/tracker.rb",
36
- "lib/trackoid/tracker_aggregates.rb",
37
- "lib/trackoid/tracking.rb",
38
- "spec/aggregates_spec.rb",
39
- "spec/ext/range_spec.rb",
40
- "spec/ext/time_spec.rb",
41
- "spec/reader_extender_spec.rb",
42
- "spec/readers_spec.rb",
43
- "spec/spec.opts",
44
- "spec/spec_helper.rb",
45
- "spec/timezone_spec.rb",
46
- "spec/trackoid_spec.rb",
47
- "trackoid.gemspec"
48
- ]
49
12
  s.homepage = "http://github.com/twoixter/trackoid"
50
- s.require_paths = ["lib"]
51
- s.rubygems_version = "1.8.24"
52
13
  s.summary = "Trackoid is an easy scalable analytics tracker using MongoDB and Mongoid"
14
+ s.description = "Trackoid uses an embeddable approach to track analytics data using the poweful features of MongoDB for scalability"
15
+ s.rubyforge_project = "trackoid"
16
+ s.require_paths = ["lib"]
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
53
20
 
54
- if s.respond_to? :specification_version then
55
- s.specification_version = 3
56
-
57
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
- s.add_runtime_dependency(%q<mongoid>, [">= 2.1.0"])
59
- s.add_development_dependency(%q<rake>, [">= 0"])
60
- s.add_development_dependency(%q<jeweler>, [">= 0"])
61
- s.add_development_dependency(%q<rspec>, [">= 2.2.0"])
62
- s.add_development_dependency(%q<mocha>, ["= 0.11.0"])
63
- else
64
- s.add_dependency(%q<mongoid>, [">= 2.1.0"])
65
- s.add_dependency(%q<rake>, [">= 0"])
66
- s.add_dependency(%q<jeweler>, [">= 0"])
67
- s.add_dependency(%q<rspec>, [">= 2.2.0"])
68
- s.add_dependency(%q<mocha>, ["= 0.11.0"])
69
- end
70
- else
71
- s.add_dependency(%q<mongoid>, [">= 2.1.0"])
72
- s.add_dependency(%q<rake>, [">= 0"])
73
- s.add_dependency(%q<jeweler>, [">= 0"])
74
- s.add_dependency(%q<rspec>, [">= 2.2.0"])
75
- s.add_dependency(%q<mocha>, ["= 0.11.0"])
76
- end
21
+ s.add_dependency 'mongoid', '~> 3.0.5'
22
+ s.add_dependency 'rake'
23
+ s.add_development_dependency 'rspec'
24
+ s.add_development_dependency 'mocha'
77
25
  end
78
-