mongo_mapper 0.5.6 → 0.5.7

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.
Files changed (39) hide show
  1. data/.gitignore +3 -1
  2. data/README.rdoc +3 -0
  3. data/VERSION +1 -1
  4. data/lib/mongo_mapper.rb +14 -6
  5. data/lib/mongo_mapper/associations.rb +11 -5
  6. data/lib/mongo_mapper/associations/base.rb +17 -5
  7. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -2
  8. data/lib/mongo_mapper/associations/many_documents_proxy.rb +15 -15
  9. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +2 -2
  10. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +1 -1
  11. data/lib/mongo_mapper/associations/proxy.rb +1 -0
  12. data/lib/mongo_mapper/callbacks.rb +18 -0
  13. data/lib/mongo_mapper/document.rb +206 -89
  14. data/lib/mongo_mapper/dynamic_finder.rb +1 -1
  15. data/lib/mongo_mapper/embedded_document.rb +7 -3
  16. data/lib/mongo_mapper/finder_options.rb +87 -66
  17. data/lib/mongo_mapper/pagination.rb +2 -0
  18. data/lib/mongo_mapper/serialization.rb +2 -3
  19. data/lib/mongo_mapper/serializers/json_serializer.rb +1 -1
  20. data/lib/mongo_mapper/support.rb +9 -0
  21. data/lib/mongo_mapper/validations.rb +3 -1
  22. data/mongo_mapper.gemspec +4 -4
  23. data/test/functional/associations/test_many_documents_as_proxy.rb +2 -2
  24. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +25 -1
  25. data/test/functional/associations/test_many_embedded_proxy.rb +25 -0
  26. data/test/functional/associations/test_many_polymorphic_proxy.rb +48 -6
  27. data/test/functional/associations/test_many_proxy.rb +27 -6
  28. data/test/functional/test_document.rb +49 -29
  29. data/test/functional/test_pagination.rb +17 -17
  30. data/test/functional/test_validations.rb +35 -14
  31. data/test/models.rb +85 -10
  32. data/test/support/{test_timing.rb → timing.rb} +1 -1
  33. data/test/test_helper.rb +8 -8
  34. data/test/unit/test_association_base.rb +17 -0
  35. data/test/unit/test_document.rb +12 -1
  36. data/test/unit/test_embedded_document.rb +13 -4
  37. data/test/unit/test_finder_options.rb +50 -48
  38. data/test/unit/test_pagination.rb +4 -0
  39. metadata +4 -4
@@ -5,7 +5,7 @@ class Test::Unit::TestCase
5
5
  end_time = Time.now
6
6
 
7
7
  duration = end_time - begin_time
8
- threshold = 0.3
8
+ threshold = 0.5
9
9
 
10
10
  if duration > threshold
11
11
  puts "\nSLOW TEST: #{duration} - #{self.name}"
@@ -1,4 +1,4 @@
1
- require File.join(File.expand_path(File.dirname(__FILE__) + '/../lib/mongo_mapper'))
1
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/mongo_mapper')
2
2
 
3
3
  gem 'jnunemaker-matchy', '0.4.0'
4
4
  gem 'shoulda', '2.10.2'
@@ -12,19 +12,19 @@ require 'mocha'
12
12
  require 'pp'
13
13
 
14
14
  require 'support/custom_matchers'
15
- require 'support/test_timing'
15
+ require 'support/timing'
16
16
 
17
17
  class Test::Unit::TestCase
18
18
  include CustomMatchers
19
-
20
- def clear_all_collections
21
- MongoMapper::Document.descendants.map { |d| d.collection.clear }
22
- end
23
19
  end
24
20
 
25
21
  DefaultDatabase = 'test' unless defined?(DefaultDatabase)
26
22
  AlternateDatabase = 'test2' unless defined?(AlternateDatabase)
27
23
 
28
- logger = Logger.new(File.expand_path(File.dirname(__FILE__) + '/../tmp/test.log'))
29
- MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017, :logger => logger)
24
+ test_dir = File.expand_path(File.dirname(__FILE__) + '/../tmp')
25
+ FileUtils.mkdir_p(test_dir) unless File.exist?(test_dir)
26
+
27
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017, {
28
+ :logger => Logger.new(test_dir + '/test.log')
29
+ })
30
30
  MongoMapper.database = DefaultDatabase
@@ -48,6 +48,23 @@ class AssociationBaseTest < Test::Unit::TestCase
48
48
  end
49
49
  end
50
50
 
51
+ context "finder_options" do
52
+ should "default to empty hash" do
53
+ base = Base.new(:many, :foos)
54
+ base.finder_options.should == {}
55
+ end
56
+
57
+ should "work with order" do
58
+ base = Base.new(:many, :foos, :order => 'position')
59
+ base.finder_options.should == {:order => 'position'}
60
+ end
61
+
62
+ should "correctly parse from options" do
63
+ base = Base.new(:many, :foos, :order => 'position', :somekey => 'somevalue')
64
+ base.finder_options.should == {:order => 'position', :somekey => 'somevalue'}
65
+ end
66
+ end
67
+
51
68
  context "belongs_to?" do
52
69
  should "be true if belongs_to" do
53
70
  Base.new(:belongs_to, :foo).belongs_to?.should be_true
@@ -47,13 +47,24 @@ class DocumentTest < Test::Unit::TestCase
47
47
  end
48
48
 
49
49
  should "default collection name to class name tableized" do
50
- class Item
50
+ class ::Item
51
51
  include MongoMapper::Document
52
52
  end
53
53
 
54
54
  Item.collection.should be_instance_of(Mongo::Collection)
55
55
  Item.collection.name.should == 'items'
56
56
  end
57
+
58
+ should "default collection name of namespaced class to tableized with dot separation" do
59
+ module ::BloggyPoo
60
+ class Post
61
+ include MongoMapper::Document
62
+ end
63
+ end
64
+
65
+ BloggyPoo::Post.collection.should be_instance_of(Mongo::Collection)
66
+ BloggyPoo::Post.collection.name.should == 'bloggy_poo.posts'
67
+ end
57
68
 
58
69
  should "allow setting the collection name" do
59
70
  @document.set_collection_name('foobar')
@@ -465,11 +465,20 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
465
465
  clone.age.should == 27
466
466
  end
467
467
  end
468
-
468
+
469
469
  context "key shorcut access" do
470
- should "be able to read key with []" do
471
- doc = @document.new(:name => 'string')
472
- doc[:name].should == 'string'
470
+ context "[]" do
471
+ should "work when key found" do
472
+ doc = @document.new(:name => 'string')
473
+ doc[:name].should == 'string'
474
+ end
475
+
476
+ should "raise exception when key not found" do
477
+ doc = @document.new(:name => 'string')
478
+ lambda {
479
+ doc[:not_here]
480
+ }.should raise_error(MongoMapper::KeyNotFound)
481
+ end
473
482
  end
474
483
 
475
484
  context "[]=" do
@@ -15,73 +15,75 @@ class FinderOptionsTest < Test::Unit::TestCase
15
15
  end
16
16
  end
17
17
 
18
- context "#criteria" do
19
- should "convert conditions to criteria" do
20
- FinderOptions.expects(:to_mongo_criteria).with(Room, :foo => 1).returns({})
21
- FinderOptions.new(Room, :conditions => {:foo => 1}).criteria
22
- end
23
- end
24
-
25
- context "#options" do
26
- should "convert options to mongo options" do
27
- FinderOptions.expects(:to_mongo_options).with(Room, :order => 'foo asc', :select => 'foo,bar').returns({})
28
- FinderOptions.new(Room, :order => 'foo asc', :select => 'foo,bar').options
29
- end
30
- end
31
-
32
18
  context "Converting conditions to criteria" do
33
19
  should "not add _type to query if model does not have superclass that is single collection inherited" do
34
- FinderOptions.to_mongo_criteria(Message, :foo => 'bar').should == {
20
+ FinderOptions.new(Message, :foo => 'bar').criteria.should == {
35
21
  :foo => 'bar'
36
22
  }
37
23
  end
38
24
 
25
+ should "not add _type to nested conditions" do
26
+ FinderOptions.new(Enter, :foo => 'bar', :age => {'$gt' => 21}).criteria.should == {
27
+ :foo => 'bar',
28
+ :age => {'$gt' => 21},
29
+ :_type => 'Enter'
30
+ }
31
+ end
32
+
33
+ %w{gt lt gte lte ne in nin mod size where exists}.each do |operator|
34
+ should "convert #{operator} conditions" do
35
+ FinderOptions.new(Room, :age.send(operator) => 21).criteria.should == {
36
+ :age => {"$#{operator}" => 21}
37
+ }
38
+ end
39
+ end
40
+
39
41
  should "automatically add _type to query if model is single collection inherited" do
40
- FinderOptions.to_mongo_criteria(Enter, :foo => 'bar').should == {
42
+ FinderOptions.new(Enter, :foo => 'bar').criteria.should == {
41
43
  :foo => 'bar',
42
44
  :_type => 'Enter'
43
45
  }
44
46
  end
45
47
 
46
48
  should "work with simple criteria" do
47
- FinderOptions.to_mongo_criteria(Room, :foo => 'bar').should == {
49
+ FinderOptions.new(Room, :foo => 'bar').criteria.should == {
48
50
  :foo => 'bar'
49
51
  }
50
52
 
51
- FinderOptions.to_mongo_criteria(Room, :foo => 'bar', :baz => 'wick').should == {
53
+ FinderOptions.new(Room, :foo => 'bar', :baz => 'wick').criteria.should == {
52
54
  :foo => 'bar',
53
55
  :baz => 'wick'
54
56
  }
55
57
  end
56
58
 
57
59
  should "convert id to _id" do
58
- FinderOptions.to_mongo_criteria(Room, :id => '1').should == {
60
+ FinderOptions.new(Room, :id => '1').criteria.should == {
59
61
  :_id => '1'
60
62
  }
61
63
  end
62
64
 
63
65
  should "use $in for arrays" do
64
- FinderOptions.to_mongo_criteria(Room, :foo => [1,2,3]).should == {
66
+ FinderOptions.new(Room, :foo => [1,2,3]).criteria.should == {
65
67
  :foo => {'$in' => [1,2,3]}
66
68
  }
67
69
  end
68
70
 
69
71
  should "not use $in for arrays if already using array operator" do
70
- FinderOptions.to_mongo_criteria(Room, :foo => {'$all' => [1,2,3]}).should == {
72
+ FinderOptions.new(Room, :foo => {'$all' => [1,2,3]}).criteria.should == {
71
73
  :foo => {'$all' => [1,2,3]}
72
74
  }
73
75
 
74
- FinderOptions.to_mongo_criteria(Room, :foo => {'$any' => [1,2,3]}).should == {
76
+ FinderOptions.new(Room, :foo => {'$any' => [1,2,3]}).criteria.should == {
75
77
  :foo => {'$any' => [1,2,3]}
76
78
  }
77
79
  end
78
80
 
79
81
  should "work arbitrarily deep" do
80
- FinderOptions.to_mongo_criteria(Room, :foo => {:bar => [1,2,3]}).should == {
82
+ FinderOptions.new(Room, :foo => {:bar => [1,2,3]}).criteria.should == {
81
83
  :foo => {:bar => {'$in' => [1,2,3]}}
82
84
  }
83
85
 
84
- FinderOptions.to_mongo_criteria(Room, :foo => {:bar => {'$any' => [1,2,3]}}).should == {
86
+ FinderOptions.new(Room, :foo => {:bar => {'$any' => [1,2,3]}}).criteria.should == {
85
87
  :foo => {:bar => {'$any' => [1,2,3]}}
86
88
  }
87
89
  end
@@ -90,103 +92,103 @@ class FinderOptionsTest < Test::Unit::TestCase
90
92
  context "ordering" do
91
93
  should "single field with ascending direction" do
92
94
  sort = [['foo', 1]]
93
- FinderOptions.to_mongo_options(Room, :order => 'foo asc')[:sort].should == sort
94
- FinderOptions.to_mongo_options(Room, :order => 'foo ASC')[:sort].should == sort
95
+ FinderOptions.new(Room, :order => 'foo asc').options[:sort].should == sort
96
+ FinderOptions.new(Room, :order => 'foo ASC').options[:sort].should == sort
95
97
  end
96
98
 
97
99
  should "single field with descending direction" do
98
100
  sort = [['foo', -1]]
99
- FinderOptions.to_mongo_options(Room, :order => 'foo desc')[:sort].should == sort
100
- FinderOptions.to_mongo_options(Room, :order => 'foo DESC')[:sort].should == sort
101
+ FinderOptions.new(Room, :order => 'foo desc').options[:sort].should == sort
102
+ FinderOptions.new(Room, :order => 'foo DESC').options[:sort].should == sort
101
103
  end
102
104
 
103
105
  should "convert field without direction to ascending" do
104
106
  sort = [['foo', 1]]
105
- FinderOptions.to_mongo_options(Room, :order => 'foo')[:sort].should == sort
107
+ FinderOptions.new(Room, :order => 'foo').options[:sort].should == sort
106
108
  end
107
109
 
108
110
  should "convert multiple fields with directions" do
109
111
  sort = [['foo', -1], ['bar', 1], ['baz', -1]]
110
- FinderOptions.to_mongo_options(Room, :order => 'foo desc, bar asc, baz desc')[:sort].should == sort
112
+ FinderOptions.new(Room, :order => 'foo desc, bar asc, baz desc').options[:sort].should == sort
111
113
  end
112
114
 
113
115
  should "convert multiple fields with some missing directions" do
114
116
  sort = [['foo', -1], ['bar', 1], ['baz', 1]]
115
- FinderOptions.to_mongo_options(Room, :order => 'foo desc, bar, baz')[:sort].should == sort
117
+ FinderOptions.new(Room, :order => 'foo desc, bar, baz').options[:sort].should == sort
116
118
  end
117
119
 
118
120
  should "just use sort if sort and order are present" do
119
121
  sort = [['$natural', 1]]
120
- FinderOptions.to_mongo_options(Room, :sort => sort, :order => 'foo asc')[:sort].should == sort
122
+ FinderOptions.new(Room, :sort => sort, :order => 'foo asc').options[:sort].should == sort
121
123
  end
122
124
 
123
125
  should "convert natural in order to proper" do
124
126
  sort = [['$natural', 1]]
125
- FinderOptions.to_mongo_options(Room, :order => '$natural asc')[:sort].should == sort
127
+ FinderOptions.new(Room, :order => '$natural asc').options[:sort].should == sort
126
128
  sort = [['$natural', -1]]
127
- FinderOptions.to_mongo_options(Room, :order => '$natural desc')[:sort].should == sort
129
+ FinderOptions.new(Room, :order => '$natural desc').options[:sort].should == sort
128
130
  end
129
131
 
130
132
  should "work for natural order ascending" do
131
- FinderOptions.to_mongo_options(Room, :sort => {'$natural' => 1})[:sort]['$natural'].should == 1
133
+ FinderOptions.new(Room, :sort => {'$natural' => 1}).options[:sort]['$natural'].should == 1
132
134
  end
133
135
 
134
136
  should "work for natural order descending" do
135
- FinderOptions.to_mongo_options(Room, :sort => {'$natural' => -1})[:sort]['$natural'].should == -1
137
+ FinderOptions.new(Room, :sort => {'$natural' => -1}).options[:sort]['$natural'].should == -1
136
138
  end
137
139
  end
138
140
 
139
141
  context "skip" do
140
142
  should "default to 0" do
141
- FinderOptions.to_mongo_options(Room, {})[:skip].should == 0
143
+ FinderOptions.new(Room, {}).options[:skip].should == 0
142
144
  end
143
145
 
144
146
  should "use skip provided" do
145
- FinderOptions.to_mongo_options(Room, :skip => 2)[:skip].should == 2
147
+ FinderOptions.new(Room, :skip => 2).options[:skip].should == 2
146
148
  end
147
149
 
148
150
  should "covert string to integer" do
149
- FinderOptions.to_mongo_options(Room, :skip => '2')[:skip].should == 2
151
+ FinderOptions.new(Room, :skip => '2').options[:skip].should == 2
150
152
  end
151
153
 
152
154
  should "convert offset to skip" do
153
- FinderOptions.to_mongo_options(Room, :offset => 1)[:skip].should == 1
155
+ FinderOptions.new(Room, :offset => 1).options[:skip].should == 1
154
156
  end
155
157
  end
156
158
 
157
159
  context "limit" do
158
160
  should "default to 0" do
159
- FinderOptions.to_mongo_options(Room, {})[:limit].should == 0
161
+ FinderOptions.new(Room, {}).options[:limit].should == 0
160
162
  end
161
163
 
162
164
  should "use limit provided" do
163
- FinderOptions.to_mongo_options(Room, :limit => 2)[:limit].should == 2
165
+ FinderOptions.new(Room, :limit => 2).options[:limit].should == 2
164
166
  end
165
167
 
166
168
  should "covert string to integer" do
167
- FinderOptions.to_mongo_options(Room, :limit => '2')[:limit].should == 2
169
+ FinderOptions.new(Room, :limit => '2').options[:limit].should == 2
168
170
  end
169
171
  end
170
172
 
171
173
  context "fields" do
172
174
  should "default to nil" do
173
- FinderOptions.to_mongo_options(Room, {})[:fields].should be(nil)
175
+ FinderOptions.new(Room, {}).options[:fields].should be(nil)
174
176
  end
175
177
 
176
178
  should "be converted to nil if empty string" do
177
- FinderOptions.to_mongo_options(Room, :fields => '')[:fields].should be(nil)
179
+ FinderOptions.new(Room, :fields => '').options[:fields].should be(nil)
178
180
  end
179
181
 
180
182
  should "be converted to nil if []" do
181
- FinderOptions.to_mongo_options(Room, :fields => [])[:fields].should be(nil)
183
+ FinderOptions.new(Room, :fields => []).options[:fields].should be(nil)
182
184
  end
183
185
 
184
186
  should "should work with array" do
185
- FinderOptions.to_mongo_options(Room, {:fields => %w(a b)})[:fields].should == %w(a b)
187
+ FinderOptions.new(Room, {:fields => %w(a b)}).options[:fields].should == %w(a b)
186
188
  end
187
189
 
188
190
  should "convert comma separated list to array" do
189
- FinderOptions.to_mongo_options(Room, {:fields => 'a, b'})[:fields].should == %w(a b)
191
+ FinderOptions.new(Room, {:fields => 'a, b'}).options[:fields].should == %w(a b)
190
192
  end
191
193
 
192
194
  should "also work as select" do
@@ -58,6 +58,10 @@ class PaginationTest < Test::Unit::TestCase
58
58
  should "know how many records to skip" do
59
59
  PaginationProxy.new(25, 2, 10).skip.should == 10
60
60
  end
61
+
62
+ should "alias offset to skip" do
63
+ PaginationProxy.new(25, 2, 10).offset.should == 10
64
+ end
61
65
 
62
66
  context "previous_page" do
63
67
  should "be nil if current page 1" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-22 00:00:00 -04:00
12
+ date: 2009-10-28 00:00:00 -04:00
13
13
  default_executable: mmconsole
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -147,7 +147,7 @@ files:
147
147
  - test/functional/test_validations.rb
148
148
  - test/models.rb
149
149
  - test/support/custom_matchers.rb
150
- - test/support/test_timing.rb
150
+ - test/support/timing.rb
151
151
  - test/test_helper.rb
152
152
  - test/unit/serializers/test_json_serializer.rb
153
153
  - test/unit/test_association_base.rb
@@ -212,7 +212,7 @@ test_files:
212
212
  - test/functional/test_validations.rb
213
213
  - test/models.rb
214
214
  - test/support/custom_matchers.rb
215
- - test/support/test_timing.rb
215
+ - test/support/timing.rb
216
216
  - test/test_helper.rb
217
217
  - test/unit/serializers/test_json_serializer.rb
218
218
  - test/unit/test_association_base.rb