mongo_mapper 0.5.6 → 0.5.7

Sign up to get free protection for your applications and to get access to all the features.
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