mongo_mapper-unstable 2010.1.22 → 2010.1.25

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2010.01.22
1
+ 2010.01.25
@@ -90,6 +90,13 @@ module MongoMapper
90
90
  collection.find(to_criteria(options)).count
91
91
  end
92
92
 
93
+ def find_each(options={})
94
+ criteria, options = to_finder_options(options)
95
+ collection.find(criteria, options).each do |doc|
96
+ yield load(doc)
97
+ end
98
+ end
99
+
93
100
  def exists?(options={})
94
101
  !count(options).zero?
95
102
  end
@@ -343,13 +350,14 @@ module MongoMapper
343
350
  end
344
351
 
345
352
  def save(options={})
353
+ options.assert_valid_keys(:validate, :safe)
346
354
  options.reverse_merge!(:validate => true)
347
- perform_validations = options.delete(:validate)
348
- !perform_validations || valid? ? create_or_update(options) : false
355
+ !options[:validate] || valid? ? create_or_update(options) : false
349
356
  end
350
357
 
351
- def save!
352
- save || raise(DocumentNotValid.new(self))
358
+ def save!(options={})
359
+ options.assert_valid_keys(:safe)
360
+ save(options) || raise(DocumentNotValid.new(self))
353
361
  end
354
362
 
355
363
  def update_attributes(attrs={})
@@ -5,14 +5,9 @@ module MongoMapper
5
5
  end
6
6
 
7
7
  def plugin(mod)
8
- if mod.const_defined?(:ClassMethods)
9
- extend mod::ClassMethods
10
- end
11
-
12
- if mod.const_defined?(:InstanceMethods)
13
- include mod::InstanceMethods
14
- end
15
-
8
+ extend mod::ClassMethods if mod.const_defined?(:ClassMethods)
9
+ include mod::InstanceMethods if mod.const_defined?(:InstanceMethods)
10
+ mod.configure(self) if mod.respond_to?(:configure)
16
11
  plugins << mod
17
12
  end
18
13
  end
@@ -1,23 +1,23 @@
1
1
  module MongoMapper
2
2
  module Plugins
3
3
  module Callbacks
4
- module InstanceMethods
5
- def self.included(model)
6
- model.class_eval do
7
- include ActiveSupport::Callbacks
4
+ def self.configure(model)
5
+ model.class_eval do
6
+ include ActiveSupport::Callbacks
8
7
 
9
- define_callbacks(
10
- :before_save, :after_save,
11
- :before_create, :after_create,
12
- :before_update, :after_update,
13
- :before_validation, :after_validation,
14
- :before_validation_on_create, :after_validation_on_create,
15
- :before_validation_on_update, :after_validation_on_update,
16
- :before_destroy, :after_destroy
17
- )
18
- end
8
+ define_callbacks(
9
+ :before_save, :after_save,
10
+ :before_create, :after_create,
11
+ :before_update, :after_update,
12
+ :before_validation, :after_validation,
13
+ :before_validation_on_create, :after_validation_on_create,
14
+ :before_validation_on_update, :after_validation_on_update,
15
+ :before_destroy, :after_destroy
16
+ )
19
17
  end
20
-
18
+ end
19
+
20
+ module InstanceMethods
21
21
  def valid?
22
22
  action = new? ? 'create' : 'update'
23
23
 
@@ -5,6 +5,18 @@ module MongoMapper
5
5
  def ==(other)
6
6
  other.is_a?(self.class) && _id == other._id
7
7
  end
8
+
9
+ def eql?(other)
10
+ self == other
11
+ end
12
+
13
+ def equal?(other)
14
+ object_id === other.object_id
15
+ end
16
+
17
+ def hash
18
+ _id.hash
19
+ end
8
20
  end
9
21
  end
10
22
  end
@@ -1,40 +1,40 @@
1
1
  module MongoMapper
2
2
  module Plugins
3
3
  module IdentityMap
4
- def self.identity_map
5
- Thread.current[:mongo_mapper_identity_map] ||= {}
4
+ def self.models
5
+ @models ||= Set.new
6
6
  end
7
-
8
- def self.identity_map=(v)
9
- Thread.current[:mongo_mapper_identity_map] = v
7
+
8
+ def self.clear
9
+ models.each { |m| m.identity_map.clear }
10
10
  end
11
11
 
12
+ def self.configure(model)
13
+ IdentityMap.models << model
14
+ end
15
+
12
16
  module ClassMethods
13
- def identity_map
14
- IdentityMap.identity_map
17
+ def inherited(descendant)
18
+ descendant.identity_map = identity_map
19
+ super
15
20
  end
16
21
 
17
- def identity_map=(v)
18
- IdentityMap.identity_map = v
22
+ def identity_map
23
+ @identity_map ||= {}
19
24
  end
20
25
 
21
- def identity_map_key(id)
22
- "#{collection.name}:#{id}"
26
+ def identity_map=(v)
27
+ @identity_map = v
23
28
  end
24
29
 
25
30
  def find_one(options={})
26
- criteria, finder_options = to_finder_options(options)
27
- document_in_map = identity_map[identity_map_key(criteria[:_id])]
28
- find_by_single_id = criteria.keys == [:_id]
29
- find_by_single_id_with_sci = criteria.keys.to_set == [:_id, :_type].to_set
30
-
31
- if find_by_single_id && document_in_map
32
- document_in_map
33
- elsif find_by_single_id_with_sci && document_in_map
34
- document_in_map
31
+ criteria, finder_options = to_finder_options(options)
32
+
33
+ if simple_find?(criteria) && identity_map.key?(criteria[:_id])
34
+ identity_map[criteria[:_id]]
35
35
  else
36
36
  super.tap do |document|
37
- remove_documents_from_map(document) unless finder_options[:fields].nil?
37
+ remove_documents_from_map(document) if selecting_fields?(finder_options)
38
38
  end
39
39
  end
40
40
  end
@@ -42,46 +42,78 @@ module MongoMapper
42
42
  def find_many(options)
43
43
  criteria, finder_options = to_finder_options(options)
44
44
  super.tap do |documents|
45
- remove_documents_from_map(documents) unless finder_options[:fields].nil?
45
+ remove_documents_from_map(documents) if selecting_fields?(finder_options)
46
46
  end
47
47
  end
48
48
 
49
49
  def load(attrs)
50
- key = identity_map_key(attrs['_id'])
51
- unless document = identity_map[key]
50
+ document = identity_map[attrs['_id']]
51
+
52
+ if document.nil? || identity_map_off?
52
53
  document = super
53
- identity_map[document.identity_map_key] = document
54
+ identity_map[document._id] = document if identity_map_on?
54
55
  end
55
56
 
56
57
  document
57
58
  end
58
-
59
+
60
+ def identity_map_status
61
+ defined?(@identity_map_status) ? @identity_map_status : true
62
+ end
63
+
64
+ def identity_map_on
65
+ @identity_map_status = true
66
+ end
67
+
68
+ def identity_map_off
69
+ @identity_map_status = false
70
+ end
71
+
72
+ def identity_map_on?
73
+ identity_map_status
74
+ end
75
+
76
+ def identity_map_off?
77
+ !identity_map_on?
78
+ end
79
+
80
+ def without_identity_map(&block)
81
+ identity_map_off
82
+ yield
83
+ ensure
84
+ identity_map_on
85
+ end
86
+
59
87
  private
60
88
  def remove_documents_from_map(*documents)
61
89
  documents.flatten.compact.each do |document|
62
- identity_map.delete(identity_map_key(document._id))
90
+ identity_map.delete(document._id)
63
91
  end
64
92
  end
93
+
94
+ def simple_find?(criteria)
95
+ criteria.keys == [:_id] || criteria.keys.to_set == [:_id, :_type].to_set
96
+ end
97
+
98
+ def selecting_fields?(options)
99
+ !options[:fields].nil?
100
+ end
65
101
  end
66
102
 
67
103
  module InstanceMethods
68
- def identity_map_key
69
- @identity_map_key ||= self.class.identity_map_key(_id)
70
- end
71
-
72
104
  def identity_map
73
105
  self.class.identity_map
74
106
  end
75
107
 
76
108
  def save(*args)
77
109
  if result = super
78
- identity_map[identity_map_key] = self
110
+ identity_map[_id] = self if self.class.identity_map_on?
79
111
  end
80
112
  result
81
113
  end
82
114
 
83
115
  def delete
84
- identity_map.delete(identity_map_key)
116
+ identity_map.delete(_id) if self.class.identity_map_on?
85
117
  super
86
118
  end
87
119
  end
@@ -1,6 +1,10 @@
1
1
  module MongoMapper
2
2
  module Plugins
3
3
  module Keys
4
+ def self.configure(model)
5
+ model.key :_id, ObjectId
6
+ end
7
+
4
8
  module ClassMethods
5
9
  def inherited(descendant)
6
10
  descendant.instance_variable_set(:@keys, keys.dup)
@@ -133,10 +137,6 @@ module MongoMapper
133
137
  end
134
138
 
135
139
  module InstanceMethods
136
- def self.included(model)
137
- model.key :_id, ObjectId
138
- end
139
-
140
140
  def initialize(attrs={}, from_db=false)
141
141
  unless attrs.nil?
142
142
  provided_keys = attrs.keys.map { |k| k.to_s }
@@ -3,6 +3,10 @@ require 'active_support/json'
3
3
  module MongoMapper
4
4
  module Plugins
5
5
  module Serialization
6
+ def self.configure(model)
7
+ model.class_eval { include Json }
8
+ end
9
+
6
10
  class Serializer
7
11
  attr_reader :options
8
12
 
@@ -96,14 +100,6 @@ module MongoMapper
96
100
  options[:except] = except
97
101
  end
98
102
  end
99
-
100
- module InstanceMethods
101
- def self.included(model)
102
- model.class_eval do
103
- include Json
104
- end
105
- end
106
- end
107
103
  end
108
104
  end
109
105
  end
@@ -1,10 +1,8 @@
1
1
  module MongoMapper
2
2
  module Plugins
3
3
  module Validations
4
- module InstanceMethods
5
- def self.included(model)
6
- model.class_eval { include Validatable }
7
- end
4
+ def self.configure(model)
5
+ model.class_eval { include Validatable }
8
6
  end
9
7
 
10
8
  module DocumentMacros
@@ -15,6 +15,14 @@ class BelongsToProxyTest < Test::Unit::TestCase
15
15
  @comment_class.new.post.nil?.should be_true
16
16
  end
17
17
 
18
+ should "send object id to target" do
19
+ post = @post_class.new(:name => 'mongomapper')
20
+ comment = @comment_class.new(:name => 'Foo!', :post => post)
21
+ comment.save
22
+
23
+ comment.post.object_id.should == comment.post.target.object_id
24
+ end
25
+
18
26
  should "have boolean presence method" do
19
27
  comment = @comment_class.new(:name => 'Foo!')
20
28
  comment.post?.should be_false
@@ -13,6 +13,18 @@ class OneProxyTest < Test::Unit::TestCase
13
13
  @post_class.new.author.nil?.should be_true
14
14
  end
15
15
 
16
+ should "send object id to target" do
17
+ @post_class.one :author, :class => @author_class
18
+
19
+ post = @post_class.new
20
+ author = @author_class.new(:name => 'Frank')
21
+ post.author = author
22
+ author.save.should be_true
23
+ post.save.should be_true
24
+
25
+ post.author.object_id.should == post.author.target.object_id
26
+ end
27
+
16
28
  should "be able to replace the association" do
17
29
  @post_class.one :author, :class => @author_class
18
30
 
@@ -338,6 +338,18 @@ class DocumentTest < Test::Unit::TestCase
338
338
  end
339
339
  end
340
340
 
341
+ context "#find_each" do
342
+ should "yield all documents found, based on criteria" do
343
+ yield_documents = []
344
+ @document.find_each(:order => "first_name") {|doc| yield_documents << doc }
345
+ yield_documents.should == [@doc1, @doc3, @doc2]
346
+
347
+ yield_documents = []
348
+ @document.find_each(:last_name => 'Nunemaker', :order => 'age desc') {|doc| yield_documents << doc }
349
+ yield_documents.should == [@doc1, @doc3]
350
+ end
351
+ end
352
+
341
353
  context "dynamic finders" do
342
354
  should "find document based on all arguments" do
343
355
  @document.find_by_first_name_and_last_name_and_age('John', 'Nunemaker', 27).should == @doc1
@@ -751,6 +763,47 @@ class DocumentTest < Test::Unit::TestCase
751
763
  @document.new(:name => 'John').save(:safe => true)
752
764
  end
753
765
  end
766
+
767
+ should "raise argument error if options has unsupported key" do
768
+ doc = @document.new
769
+ assert_raises(ArgumentError) { doc.save(:foo => true) }
770
+ end
771
+ end
772
+
773
+ context "#save! (with options)" do
774
+ setup do
775
+ MongoMapper.ensured_indexes = []
776
+
777
+ @document = Doc do
778
+ key :name, String
779
+ set_collection_name 'test_indexes'
780
+ ensure_index :name, :unique => true
781
+ end
782
+
783
+ if @document.database.collection_names.include?(@document.collection.name)
784
+ @document.collection.drop_indexes
785
+ end
786
+
787
+ MongoMapper.ensure_indexes!
788
+ end
789
+
790
+ should "allow passing safe" do
791
+ doc = @document.create(:name => 'John')
792
+
793
+ assert_raises(Mongo::OperationFailure) do
794
+ @document.new(:name => 'John').save!(:safe => true)
795
+ end
796
+ end
797
+
798
+ should "raise argument error if options has unsupported key" do
799
+ doc = @document.new
800
+ assert_raises(ArgumentError) { doc.save!(:foo => true) }
801
+ end
802
+
803
+ should "raise argument error if using validate as that would be pointless with save!" do
804
+ doc = @document.new
805
+ assert_raises(ArgumentError) { doc.save!(:validate => false) }
806
+ end
754
807
  end
755
808
 
756
809
  context "#destroy" do
@@ -1,34 +1,40 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class IdentityMapTest < Test::Unit::TestCase
4
- def assert_in_map(resource)
5
- resource.identity_map.keys.should include(resource.identity_map_key)
6
- mapped_resource = resource.identity_map[resource.identity_map_key]
7
- resource.object_id.should == mapped_resource.object_id
4
+ def assert_in_map(*resources)
5
+ [resources].flatten.each do |resource|
6
+ resource.identity_map.keys.should include(resource._id)
7
+ mapped_resource = resource.identity_map[resource._id]
8
+ resource.should equal(mapped_resource)
9
+ end
8
10
  end
9
-
10
- def assert_not_in_map(resource)
11
- resource.identity_map.keys.should_not include(resource.identity_map_key)
11
+
12
+ def assert_not_in_map(*resources)
13
+ [resources].flatten.each do |resource|
14
+ resource.identity_map.keys.should_not include(resource._id)
15
+ end
12
16
  end
13
-
17
+
14
18
  def expect_no_queries
15
19
  Mongo::Collection.any_instance.expects(:find_one).never
16
20
  Mongo::Collection.any_instance.expects(:find).never
17
21
  end
18
-
22
+
19
23
  def expects_one_query
20
24
  Mongo::Collection.any_instance.expects(:find_one).once.returns({})
21
25
  end
22
-
26
+
23
27
  context "Document" do
24
28
  setup do
29
+ MongoMapper::Plugins::IdentityMap.models.clear
30
+
25
31
  @person_class = Doc('Person') do
26
32
  set_collection_name 'people'
27
33
  plugin MongoMapper::Plugins::IdentityMap
28
34
 
29
35
  key :name, String
30
36
  end
31
-
37
+
32
38
  @post_class = Doc('Post') do
33
39
  set_collection_name 'posts'
34
40
  plugin MongoMapper::Plugins::IdentityMap
@@ -36,35 +42,62 @@ class IdentityMapTest < Test::Unit::TestCase
36
42
  key :title, String
37
43
  key :person_id, ObjectId
38
44
  end
39
-
45
+
40
46
  @post_class.belongs_to :person, :class => @person_class
41
47
  @person_class.many :posts, :class => @post_class
42
-
43
- @person_class.identity_map.clear
44
- @post_class.identity_map.clear
48
+
49
+ @post_class.identity_map_on
50
+ @person_class.identity_map_on
51
+ MongoMapper::Plugins::IdentityMap.clear
45
52
  end
46
53
 
47
- should "default identity map to hash" do
48
- Doc() do
49
- plugin MongoMapper::Plugins::IdentityMap
50
- end.identity_map.should == {}
54
+ should "track identity mapped models" do
55
+ MongoMapper::Plugins::IdentityMap.models.should == [@person_class, @post_class].to_set
51
56
  end
52
57
 
53
- should "share identity map with other classes" do
54
- map = @post_class.identity_map
55
- map.object_id.should == @person_class.identity_map.object_id
58
+ should "be able to clear the map of all models" do
59
+ person = @person_class.create(:name => 'John')
60
+ post = @post_class.create(:title => 'IM 4eva')
61
+ assert_in_map(person, post)
62
+
63
+ MongoMapper::Plugins::IdentityMap.clear
64
+
65
+ assert_not_in_map(person, post)
66
+
67
+ [@person_class, @post_class].each { |klass| klass.identity_map.should == {} }
56
68
  end
69
+
70
+ context "IM on off status" do
71
+ teardown do
72
+ @post_class.identity_map_on
73
+ @person_class.identity_map_on
74
+ end
57
75
 
58
- should "have identity map key that is always unique per document and class" do
59
- person = @person_class.new
60
- person.identity_map_key.should == "people:#{person.id}"
61
- @person_class.identity_map_key(person.id).should == person.identity_map_key
76
+ should "default identity map status to on" do
77
+ Doc { plugin MongoMapper::Plugins::IdentityMap }.identity_map_status.should be_true
78
+ end
79
+
80
+ should "be true if on" do
81
+ @post_class.identity_map_on
82
+ @post_class.should be_identity_map_on
83
+ @post_class.should_not be_identity_map_off
84
+ end
62
85
 
63
- post = @post_class.new
64
- post.identity_map_key.should == "posts:#{post.id}"
65
- @post_class.identity_map_key(post.id).should == post.identity_map_key
86
+ should "be false if off" do
87
+ @post_class.identity_map_off
88
+ @post_class.should be_identity_map_off
89
+ @post_class.should_not be_identity_map_on
90
+ end
66
91
 
67
- person.identity_map_key.should_not == post.identity_map_key
92
+ should "not share with other classes" do
93
+ @post_class.identity_map_off
94
+ @person_class.identity_map_on
95
+ @post_class.identity_map_status.should_not == @person_class.identity_map_status
96
+ end
97
+ end
98
+
99
+ should "default identity map to hash" do
100
+ Doc { plugin MongoMapper::Plugins::IdentityMap }.identity_map.should == {}
68
101
  end
69
102
 
70
103
  should "add key to map when saved" do
@@ -73,7 +106,7 @@ class IdentityMapTest < Test::Unit::TestCase
73
106
  person.save.should be_true
74
107
  assert_in_map(person)
75
108
  end
76
-
109
+
77
110
  should "allow saving with options" do
78
111
  person = @person_class.new
79
112
  assert_nothing_raised do
@@ -87,7 +120,7 @@ class IdentityMapTest < Test::Unit::TestCase
87
120
  person.destroy
88
121
  assert_not_in_map(person)
89
122
  end
90
-
123
+
91
124
  context "reload" do
92
125
  setup do
93
126
  @person = @person_class.create(:name => 'Fred')
@@ -101,8 +134,8 @@ class IdentityMapTest < Test::Unit::TestCase
101
134
 
102
135
  should "add object back into map" do
103
136
  assert_in_map(@person)
104
- object_id = @person.object_id
105
- @person.reload.object_id.should == object_id
137
+ before_reload = @person
138
+ @person.reload.should equal(before_reload)
106
139
  assert_in_map(@person)
107
140
  end
108
141
  end
@@ -121,10 +154,10 @@ class IdentityMapTest < Test::Unit::TestCase
121
154
  first_load = @person_class.load({'_id' => @id, 'name' => 'Frank'})
122
155
  @person_class.identity_map.expects(:[]=).never
123
156
  second_load = @person_class.load({'_id' => @id, 'name' => 'Frank'})
124
- first_load.object_id.should == second_load.object_id
157
+ first_load.should equal(second_load)
125
158
  end
126
159
  end
127
-
160
+
128
161
  context "#find (with one id)" do
129
162
  context "for object not in map" do
130
163
  setup do
@@ -142,7 +175,7 @@ class IdentityMapTest < Test::Unit::TestCase
142
175
  found_person = @person_class.find(@person.id)
143
176
  assert_in_map(found_person)
144
177
  end
145
-
178
+
146
179
  should "return nil if not found " do
147
180
  @person_class.find(1234).should be_nil
148
181
  end
@@ -157,15 +190,15 @@ class IdentityMapTest < Test::Unit::TestCase
157
190
  expect_no_queries
158
191
  @person_class.find(@person.id)
159
192
  end
160
-
193
+
161
194
  should "return exact object" do
162
195
  assert_in_map(@person)
163
196
  found_person = @person_class.find(@person.id)
164
- found_person.object_id.should == @person.object_id
197
+ found_person.should equal(@person)
165
198
  end
166
199
  end
167
200
  end
168
-
201
+
169
202
  context "#find (with one id and options)" do
170
203
  setup do
171
204
  @person = @person_class.create(:name => 'Fred')
@@ -195,7 +228,7 @@ class IdentityMapTest < Test::Unit::TestCase
195
228
  @person.posts.find(1234).should be_nil
196
229
  end
197
230
  end
198
-
231
+
199
232
  context "#find (with multiple ids)" do
200
233
  should "add all documents to map" do
201
234
  person1 = @person_class.create(:name => 'Fred')
@@ -204,7 +237,7 @@ class IdentityMapTest < Test::Unit::TestCase
204
237
  @person_class.identity_map.clear
205
238
 
206
239
  people = @person_class.find(person1.id, person2.id, person3.id)
207
- people.each { |person| assert_in_map(person) }
240
+ assert_in_map(people)
208
241
  end
209
242
 
210
243
  should "add missing documents to map and return existing ones" do
@@ -214,16 +247,14 @@ class IdentityMapTest < Test::Unit::TestCase
214
247
  person3 = @person_class.create(:name => 'Jesse')
215
248
 
216
249
  assert_not_in_map(person1)
217
- assert_in_map(person2)
218
- assert_in_map(person3)
250
+ assert_in_map(person2, person3)
219
251
 
220
252
  people = @person_class.find(person1.id, person2.id, person3.id)
221
253
  assert_in_map(people.first) # making sure one that wasn't mapped now is
222
- assert_in_map(person2)
223
- assert_in_map(person3)
254
+ assert_in_map(person2, person3)
224
255
  end
225
256
  end
226
-
257
+
227
258
  context "#first" do
228
259
  context "for object not in map" do
229
260
  setup do
@@ -256,15 +287,15 @@ class IdentityMapTest < Test::Unit::TestCase
256
287
  expect_no_queries
257
288
  @person_class.first(:_id => @person.id)
258
289
  end
259
-
290
+
260
291
  should "return exact object" do
261
292
  assert_in_map(@person)
262
293
  found_person = @person_class.first(:_id => @person.id)
263
- found_person.object_id.should == @person.object_id
294
+ found_person.should equal(@person)
264
295
  end
265
296
  end
266
297
  end
267
-
298
+
268
299
  context "#all" do
269
300
  should "add all documents to map" do
270
301
  person1 = @person_class.create(:name => 'Fred')
@@ -273,7 +304,7 @@ class IdentityMapTest < Test::Unit::TestCase
273
304
  @person_class.identity_map.clear
274
305
 
275
306
  people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
276
- people.each { |person| assert_in_map(person) }
307
+ assert_in_map(people)
277
308
  end
278
309
 
279
310
  should "add missing documents to map and return existing ones" do
@@ -283,13 +314,11 @@ class IdentityMapTest < Test::Unit::TestCase
283
314
  person3 = @person_class.create(:name => 'Jesse')
284
315
 
285
316
  assert_not_in_map(person1)
286
- assert_in_map(person2)
287
- assert_in_map(person3)
317
+ assert_in_map(person2, person3)
288
318
 
289
319
  people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
290
- assert_in_map(people.first) # making sure one that wasn't mapped now is
291
- assert_in_map(person2)
292
- assert_in_map(person3)
320
+ # people.first is making sure one that wasn't mapped now is
321
+ assert_in_map(people.first, person2, person3)
293
322
  end
294
323
  end
295
324
 
@@ -303,7 +332,7 @@ class IdentityMapTest < Test::Unit::TestCase
303
332
  @person_class.find_by_id(1234).should be_nil
304
333
  end
305
334
  end
306
-
335
+
307
336
  context "querying and selecting certain fields" do
308
337
  setup do
309
338
  @person = @person_class.create(:name => 'Bill')
@@ -324,8 +353,8 @@ class IdentityMapTest < Test::Unit::TestCase
324
353
  @person_class.find(1234, :select => 'name').should be_nil
325
354
  end
326
355
  end
327
-
328
- context "single collection inheritance" do
356
+
357
+ context "single collection inherited models" do
329
358
  setup do
330
359
  class ::Item
331
360
  include MongoMapper::Document
@@ -339,10 +368,9 @@ class IdentityMapTest < Test::Unit::TestCase
339
368
  one :child, :class_name => 'Blog'
340
369
  end
341
370
  Item.collection.remove
342
- Item.identity_map.clear
343
371
 
344
372
  class ::Blog < ::Item; end
345
-
373
+
346
374
  class ::BlogPost < ::Item
347
375
  key :blog_id, ObjectId
348
376
  belongs_to :blog
@@ -355,11 +383,10 @@ class IdentityMapTest < Test::Unit::TestCase
355
383
  Object.send :remove_const, 'BlogPost' if defined?(::BlogPost)
356
384
  end
357
385
 
358
- should "share the same identity map 4eva" do
386
+ should "share the same identity map" do
359
387
  blog = Blog.create(:title => 'Jill')
360
388
  assert_in_map(blog)
361
- Item.identity_map_key(blog).should == Blog.identity_map_key(blog)
362
- Item.identity_map.object_id.should == Blog.identity_map.object_id
389
+ Item.identity_map.should equal(Blog.identity_map)
363
390
  end
364
391
 
365
392
  should "not query when finding by _id and _type" do
@@ -369,8 +396,7 @@ class IdentityMapTest < Test::Unit::TestCase
369
396
 
370
397
  blog = Item.find(blog.id)
371
398
  post = Item.find(post.id)
372
- assert_in_map(blog)
373
- assert_in_map(post)
399
+ assert_in_map(blog, post)
374
400
 
375
401
  expect_no_queries
376
402
  post.blog
@@ -379,7 +405,7 @@ class IdentityMapTest < Test::Unit::TestCase
379
405
 
380
406
  should "load from map when using parent collection inherited class" do
381
407
  blog = Blog.create(:title => 'Jill')
382
- Item.find(blog.id).object_id.should == blog.object_id
408
+ Item.find(blog.id).should equal(blog)
383
409
  end
384
410
 
385
411
  should "work correctly with belongs to proxy" do
@@ -388,7 +414,7 @@ class IdentityMapTest < Test::Unit::TestCase
388
414
 
389
415
  blog = Blog.create(:title => 'Jill', :parent => root)
390
416
  assert_in_map(blog)
391
- root.object_id.should == blog.parent.object_id
417
+ root.should equal(blog.parent)
392
418
  end
393
419
 
394
420
  should "work correctly with one proxy" do
@@ -397,8 +423,79 @@ class IdentityMapTest < Test::Unit::TestCase
397
423
 
398
424
  root = Item.create(:title => 'Root', :child => blog)
399
425
  assert_in_map(root)
426
+ root.child.should equal(blog)
427
+ end
428
+ end
429
+
430
+ context "without identity map" do
431
+ should "not add to map on save" do
432
+ @post_class.without_identity_map do
433
+ post = @post_class.create(:title => 'Bill')
434
+ assert_not_in_map(post)
435
+ end
436
+ end
437
+
438
+ should "not remove from map on delete" do
439
+ post = @post_class.create(:title => 'Bill')
440
+ assert_in_map(post)
441
+
442
+ @post_class.without_identity_map do
443
+ post.destroy
444
+ end
445
+
446
+ assert_in_map(post)
447
+ end
448
+
449
+ should "not add to map when loading" do
450
+ @post_class.without_identity_map do
451
+ post = @post_class.load({'_id' => Mongo::ObjectID.new, 'title' => 'Awesome!'})
452
+ assert_not_in_map(post)
453
+ end
454
+ end
455
+
456
+ should "not load from map when loading" do
457
+ post = @post_class.create(:title => 'Awesome!')
400
458
 
401
- root.child.object_id.should == blog.object_id
459
+ @post_class.without_identity_map do
460
+ loaded = @post_class.load('_id' => post._id, 'title' => 'Awesome!')
461
+ loaded.should_not equal(post)
462
+ end
463
+ end
464
+
465
+ context "all" do
466
+ should "not add to map" do
467
+ @post_class.without_identity_map do
468
+ post1 = @post_class.create(:title => 'Foo')
469
+ post2 = @post_class.create(:title => 'Bar')
470
+ @post_class.identity_map.clear
471
+
472
+ assert_not_in_map(@post_class.all)
473
+ end
474
+ end
475
+ end
476
+
477
+ context "first" do
478
+ should "not add to map" do
479
+ @post_class.without_identity_map do
480
+ post1 = @post_class.create(:title => 'Foo')
481
+ post2 = @post_class.create(:title => 'Bar')
482
+ @post_class.identity_map.clear
483
+
484
+ assert_not_in_map(@post_class.first)
485
+ end
486
+ end
487
+ end
488
+
489
+ context "last" do
490
+ should "not add to map" do
491
+ @post_class.without_identity_map do
492
+ post1 = @post_class.create(:title => 'Foo')
493
+ post2 = @post_class.create(:title => 'Bar')
494
+ @post_class.identity_map.clear
495
+
496
+ assert_not_in_map(@post_class.last(:order => 'title'))
497
+ end
498
+ end
402
499
  end
403
500
  end
404
501
  end
@@ -8,10 +8,12 @@ class FakeBlankProxy < MongoMapper::Plugins::Associations::Proxy
8
8
  def find_target; '' end
9
9
  end
10
10
 
11
+ class FakeNumberProxy < MongoMapper::Plugins::Associations::Proxy
12
+ def find_target; 17 end
13
+ end
14
+
11
15
  class FakeProxy < MongoMapper::Plugins::Associations::Proxy
12
- def find_target
13
- [1, 2]
14
- end
16
+ def find_target; [1, 2] end
15
17
  end
16
18
 
17
19
  class ProxyTest < Test::Unit::TestCase
@@ -186,6 +186,34 @@ class DocumentTest < Test::Unit::TestCase
186
186
  @oid = Mongo::ObjectID.new
187
187
  end
188
188
 
189
+ should "delegate hash to _id" do
190
+ doc = @document.new
191
+ doc.hash.should == doc._id.hash
192
+ end
193
+
194
+ should "delegate eql to ==" do
195
+ doc = @document.new
196
+ other = @document.new
197
+ doc.eql?(other).should == (doc == other)
198
+ doc.eql?(doc).should == (doc == doc)
199
+ end
200
+
201
+ should "know if same object as another" do
202
+ doc = @document.new
203
+ doc.should equal(doc)
204
+ doc.should_not equal(@document.new)
205
+ end
206
+
207
+ should "allow set operations on array of documents" do
208
+ @document.key :parent_id, ObjectId
209
+ @document.belongs_to :parent, :class => @document
210
+
211
+ parent = @document.create
212
+ child = @document.create(:parent => parent)
213
+
214
+ ([child.parent] & [parent]).should == [parent]
215
+ end
216
+
189
217
  should "be equal if id and class are the same" do
190
218
  (@document.new('_id' => @oid) == @document.new('_id' => @oid)).should be(true)
191
219
  end
@@ -566,6 +566,30 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
566
566
  setup do
567
567
  @oid = Mongo::ObjectID.new
568
568
  end
569
+
570
+ should "delegate hash to _id" do
571
+ doc = @document.new
572
+ doc.hash.should == doc._id.hash
573
+ end
574
+
575
+ should "delegate eql to ==" do
576
+ doc = @document.new
577
+ other = @document.new
578
+ doc.eql?(other).should == (doc == other)
579
+ doc.eql?(doc).should == (doc == doc)
580
+ end
581
+
582
+ should "know if same object as another" do
583
+ doc = @document.new
584
+ doc.should equal(doc)
585
+ doc.should_not equal(@document.new)
586
+ end
587
+
588
+ should "allow set operations on array of documents" do
589
+ doc = @document.new
590
+ ([doc] & [doc]).should == [doc]
591
+ end
592
+
569
593
  should "be equal if id and class are the same" do
570
594
  (@document.new('_id' => @oid) == @document.new('_id' => @oid)).should be_true
571
595
  end
@@ -1,12 +1,16 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module MyPlugin
4
+ def self.configure(model)
5
+ model.class_eval { attr_accessor :from_configure }
6
+ end
7
+
4
8
  module ClassMethods
5
9
  def class_foo
6
10
  'class_foo'
7
11
  end
8
12
  end
9
-
13
+
10
14
  module InstanceMethods
11
15
  def instance_foo
12
16
  'instance_foo'
@@ -26,15 +30,19 @@ class PluginsTest < Test::Unit::TestCase
26
30
  should "include instance methods" do
27
31
  @document.new.instance_foo.should == 'instance_foo'
28
32
  end
29
-
33
+
30
34
  should "extend class methods" do
31
35
  @document.class_foo.should == 'class_foo'
32
36
  end
33
-
37
+
38
+ should "pass model to configure" do
39
+ @document.new.should respond_to(:from_configure)
40
+ end
41
+
34
42
  should "default plugins to empty array" do
35
43
  Class.new { extend MongoMapper::Plugins }.plugins.should == []
36
44
  end
37
-
45
+
38
46
  should "add plugin to plugins" do
39
47
  @document.plugins.should include(MyPlugin)
40
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper-unstable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2010.1.22
4
+ version: 2010.1.25
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: 2010-01-22 00:00:00 -05:00
12
+ date: 2010-01-25 00:00:00 -05:00
13
13
  default_executable: mmconsole
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency