mongo_mapper 0.8.3 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/UPGRADES +7 -0
  2. data/examples/attr_accessible.rb +22 -0
  3. data/examples/attr_protected.rb +22 -0
  4. data/examples/cache_key.rb +24 -0
  5. data/examples/custom_types.rb +24 -0
  6. data/examples/identity_map/automatic.rb +8 -0
  7. data/examples/identity_map/middleware.rb +14 -0
  8. data/examples/identity_map.rb +33 -0
  9. data/examples/validating/embedded_docs.rb +29 -0
  10. data/lib/mongo_mapper/extensions/object_id.rb +1 -1
  11. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +0 -1
  12. data/lib/mongo_mapper/plugins/associations/proxy.rb +17 -0
  13. data/lib/mongo_mapper/plugins/clone.rb +3 -0
  14. data/lib/mongo_mapper/plugins/dirty.rb +10 -6
  15. data/lib/mongo_mapper/plugins/embedded_document.rb +3 -4
  16. data/lib/mongo_mapper/plugins/identity_map.rb +1 -1
  17. data/lib/mongo_mapper/plugins/keys/key.rb +1 -1
  18. data/lib/mongo_mapper/plugins/keys.rb +12 -13
  19. data/lib/mongo_mapper/plugins/serialization.rb +3 -3
  20. data/lib/mongo_mapper/plugins/validations.rb +3 -3
  21. data/lib/mongo_mapper/version.rb +1 -1
  22. data/rails/init.rb +19 -0
  23. data/test/functional/associations/test_belongs_to_proxy.rb +1 -1
  24. data/test/functional/associations/test_many_documents_proxy.rb +31 -1
  25. data/test/functional/associations/test_one_embedded_proxy.rb +14 -0
  26. data/test/functional/test_caching.rb +1 -1
  27. data/test/functional/test_document.rb +1 -1
  28. data/test/functional/test_identity_map.rb +12 -4
  29. data/test/functional/test_querying.rb +6 -6
  30. data/test/functional/test_string_id_compatibility.rb +1 -1
  31. data/test/test_helper.rb +2 -2
  32. data/test/unit/serializers/test_json_serializer.rb +15 -0
  33. data/test/unit/test_clone.rb +1 -1
  34. data/test/unit/test_document.rb +3 -3
  35. data/test/unit/test_embedded_document.rb +5 -5
  36. data/test/unit/test_extensions.rb +7 -7
  37. data/test/unit/test_key.rb +2 -2
  38. data/test/unit/test_validations.rb +20 -0
  39. metadata +20 -11
data/UPGRADES ADDED
@@ -0,0 +1,7 @@
1
+ 0.7.6 => 0.8
2
+ * Proxy#owner has been removed in favor of Proxy#proxy_owner
3
+ * @new instance variable renamed to @_new (you shouldn't be using this anyway)
4
+ * Removed undefining of object_id in proxies and equal? method in Equality. This means checking equal? for a proxy and a regular document will always be false even if proxy refers to same document. Check Proxy#target instead. (ie: root.equal?(item.root.target))
5
+ * find no longer takes options as a last argument. It only works with id, multiple ids, array of ids.
6
+ * MongoMapper::MongoMapperError is now MongoMapper::Error
7
+ * metaclass, meta_eval, meta_def, class_def removed as they were not being used
@@ -0,0 +1,22 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+
4
+ MongoMapper.database = 'testing'
5
+
6
+ class User
7
+ include MongoMapper::Document
8
+ key :email, String
9
+ key :admin, Boolean, :default => false
10
+
11
+ # Only accessible or protected can be used, they cannot be used together
12
+ attr_accessible :email
13
+ end
14
+
15
+ # only accessible are set on new/create/etc.
16
+ user = User.create(:email => 'IDontLowerCaseThings@gmail.com', :admin => true)
17
+ puts user.admin # false
18
+
19
+ # can be set using accessor
20
+ user.admin = true
21
+ user.save
22
+ puts user.admin # true
@@ -0,0 +1,22 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+
4
+ MongoMapper.database = 'testing'
5
+
6
+ class User
7
+ include MongoMapper::Document
8
+ key :email, String
9
+ key :admin, Boolean, :default => false
10
+
11
+ # Only accessible or protected can be used, they cannot be used together
12
+ attr_protected :admin
13
+ end
14
+
15
+ # protected are ignored on new/create/etc.
16
+ user = User.create(:email => 'IDontLowerCaseThings@gmail.com', :admin => true)
17
+ puts user.admin # false
18
+
19
+ # can be set using accessor
20
+ user.admin = true
21
+ user.save
22
+ puts user.admin # true
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+
4
+ MongoMapper.database = 'testing'
5
+
6
+ class User
7
+ include MongoMapper::Document
8
+ end
9
+
10
+ # New Documents
11
+ puts User.new.cache_key # User/new
12
+
13
+ # Created Documents
14
+ puts User.create.cache_key # User/:id (ie: User/4c7a940cbcd1b3319b000003)
15
+
16
+ # With Suffix
17
+ puts User.create.cache_key(:foo) # User/:id/foo
18
+
19
+ # With Multiple Suffixes
20
+ puts User.create.cache_key(:foo, :bar, :baz) # User/:id/foo/bar/baz
21
+
22
+ # When updated_at key exists it will be used
23
+ User.timestamps!
24
+ puts User.create.cache_key # User/:id-:updated_at (ie: User/4c7a940cbcd1b3319b000003-20100829170828)
@@ -0,0 +1,24 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+ require 'pp'
4
+
5
+ MongoMapper.database = 'testing'
6
+
7
+ class DowncasedString
8
+ # to_mongo gets called anytime a value is assigned
9
+ def self.to_mongo(value)
10
+ value.nil? ? nil : value.to_s.downcase
11
+ end
12
+
13
+ # from mongo gets called anytime a value is read
14
+ def self.from_mongo(value)
15
+ value.nil? ? nil : value.to_s.downcase
16
+ end
17
+ end
18
+
19
+ class User
20
+ include MongoMapper::Document
21
+ key :email, DowncasedString
22
+ end
23
+
24
+ pp User.create(:email => 'IDontLowerCaseThings@gmail.com')
@@ -0,0 +1,8 @@
1
+ # Using the following will turn on identity map for all models
2
+ module IdentityMapAddition
3
+ def self.included(model)
4
+ model.plugin MongoMapper::Plugins::IdentityMap
5
+ end
6
+ end
7
+
8
+ MongoMapper::Document.append_inclusions(IdentityMapAddition)
@@ -0,0 +1,14 @@
1
+ # To use this, add the following line in environment.rb
2
+ # config.middleware.use 'PerRequestIdentityMap'
3
+ class PerRequestIdentityMap
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ MongoMapper::Plugins::IdentityMap.clear
10
+ @app.call(env)
11
+ ensure
12
+ MongoMapper::Plugins::IdentityMap.clear
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+ require 'pp'
4
+
5
+ MongoMapper.database = 'testing'
6
+
7
+ class User
8
+ include MongoMapper::Document
9
+ plugin MongoMapper::Plugins::IdentityMap
10
+
11
+ key :name, String
12
+ end
13
+ User.delete_all
14
+
15
+ user = User.create(:name => 'John')
16
+
17
+ # User gets added to map on save
18
+ pp User.identity_map[user.id]
19
+
20
+ # Does not matter how you find user, it is always the same object until the identity map is cleared
21
+ puts "#{User.identity_map[user.id].object_id} == #{user.object_id}"
22
+ puts "#{User.find(user.id).object_id} == #{user.object_id}"
23
+ puts "#{User.all[0].object_id} == #{user.object_id}"
24
+
25
+ MongoMapper::Plugins::IdentityMap.clear
26
+ puts "#{User.find(user.id).object_id} != #{user.object_id}"
27
+
28
+ # User gets removed from map on destroy
29
+ user = User.create
30
+ user.destroy
31
+ puts "Should be nil: " + User.identity_map[user.id].inspect
32
+
33
+
@@ -0,0 +1,29 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+ require 'pp'
4
+
5
+ MongoMapper.database = 'testing'
6
+
7
+ class Field
8
+ include MongoMapper::EmbeddedDocument
9
+ key :name
10
+ validates_presence_of :name
11
+ end
12
+
13
+ class Template
14
+ include MongoMapper::Document
15
+ key :name
16
+ many :fields
17
+
18
+ # This tells the template to validate all
19
+ # fields when validating the template.
20
+ validates_associated :fields
21
+ end
22
+
23
+ # Name is missing on embedded field
24
+ template = Template.new(:fields => [Field.new])
25
+ puts template.valid? # false
26
+
27
+ # Name is present on embedded field
28
+ template = Template.new(:fields => [Field.new(:name => 'Yay')])
29
+ puts template.valid? # true
@@ -17,7 +17,7 @@ class ObjectId
17
17
  extend MongoMapper::Extensions::ObjectId
18
18
  end
19
19
 
20
- class BSON::ObjectID
20
+ class BSON::ObjectId
21
21
  alias_method :original_to_json, :to_json
22
22
 
23
23
  def as_json(options=nil)
@@ -96,7 +96,6 @@ module MongoMapper
96
96
  end
97
97
 
98
98
  def apply_scope(doc)
99
- ensure_owner_saved
100
99
  criteria.each { |key, value| doc[key] = value }
101
100
  doc
102
101
  end
@@ -25,6 +25,23 @@ module MongoMapper
25
25
  reset
26
26
  end
27
27
 
28
+ # Active support in rails 3 beta 4 can override to_json after this is loaded,
29
+ # at least when run in mongomapper tests. The implementation was changed in master
30
+ # some time after this, so not sure whether this is still a problem.
31
+ #
32
+ # In rails 2, this isn't a problem however it also solves an issue where
33
+ # to_json isn't forwarded because it supports to_json itself
34
+ def to_json(*options)
35
+ load_target
36
+ target.to_json(*options)
37
+ end
38
+
39
+ # see comments to to_json
40
+ def as_json(*options)
41
+ load_target
42
+ target.as_json(*options)
43
+ end
44
+
28
45
  def inspect
29
46
  load_target
30
47
  target.inspect
@@ -7,6 +7,9 @@ module MongoMapper
7
7
  @_new = true
8
8
  @_destroyed = false
9
9
  default_id_value({})
10
+ associations.each do |name, association|
11
+ instance_variable_set(association.ivar, nil)
12
+ end
10
13
  self.attributes = other.attributes.clone.except(:_id).inject({}) do |hash, entry|
11
14
  key, value = entry
12
15
  hash[key] = value.duplicable? ? value.clone : value
@@ -39,25 +39,29 @@ module MongoMapper
39
39
  changed.inject({}) { |h, key| h[key] = key_change(key); h }
40
40
  end
41
41
 
42
- def initialize(*args)
43
- super
44
- changed_keys.clear if args.first.blank? || !new?
42
+ def initialize(*)
43
+ # never register initial id assignment as a change
44
+ super.tap { changed_keys.delete('_id') }
45
45
  end
46
46
 
47
- def save(*args)
47
+ def initialize_from_database(*)
48
+ super.tap { changed_keys.clear }
49
+ end
50
+
51
+ def save(*)
48
52
  if status = super
49
53
  changed_keys.clear
50
54
  end
51
55
  status
52
56
  end
53
57
 
54
- def save!(*args)
58
+ def save!(*)
55
59
  status = super
56
60
  changed_keys.clear
57
61
  status
58
62
  end
59
63
 
60
- def reload(*args)
64
+ def reload(*)
61
65
  document = super
62
66
  changed_keys.clear
63
67
  document
@@ -4,7 +4,7 @@ module MongoMapper
4
4
  module EmbeddedDocument
5
5
  def self.configure(model)
6
6
  model.class_eval do
7
- attr_reader :_root_document, :_parent_document
7
+ attr_accessor :_parent_document
8
8
  end
9
9
  end
10
10
 
@@ -39,9 +39,8 @@ module MongoMapper
39
39
  end
40
40
  end
41
41
 
42
- def _parent_document=(value)
43
- @_root_document = value._root_document
44
- @_parent_document = value
42
+ def _root_document
43
+ @_root_document ||= _parent_document.try(:_root_document)
45
44
  end
46
45
  end
47
46
  end
@@ -41,7 +41,7 @@ module MongoMapper
41
41
  def find_one(opts={})
42
42
  query = clone.update(opts)
43
43
 
44
- if query.simple? && model.identity_map[query[:_id]]
44
+ if model.identity_map_on? && query.simple? && model.identity_map[query[:_id]]
45
45
  model.identity_map[query[:_id]]
46
46
  else
47
47
  super.tap do |doc|
@@ -22,7 +22,7 @@ module MongoMapper
22
22
  end
23
23
 
24
24
  def can_default_id?
25
- type && [ObjectId, BSON::ObjectID, String].include?(type)
25
+ type && [ObjectId, BSON::ObjectId, String].include?(type)
26
26
  end
27
27
 
28
28
  def number?
@@ -63,11 +63,10 @@ module MongoMapper
63
63
  def load(attrs)
64
64
  return nil if attrs.nil?
65
65
  begin
66
- klass = attrs['_type'].present? ? attrs['_type'].constantize : self
67
- klass.new(attrs, true)
66
+ attrs['_type'].present? ? attrs['_type'].constantize : self
68
67
  rescue NameError
69
- new(attrs, true)
70
- end
68
+ self
69
+ end.allocate.initialize_from_database(attrs)
71
70
  end
72
71
 
73
72
  private
@@ -160,16 +159,16 @@ module MongoMapper
160
159
  end
161
160
 
162
161
  module InstanceMethods
163
- def initialize(attrs={}, from_database=false)
162
+ def initialize(attrs={})
164
163
  default_id_value(attrs)
164
+ @_new = true
165
+ assign(attrs)
166
+ end
165
167
 
166
- if from_database
167
- @_new = false
168
- load_from_database(attrs)
169
- else
170
- @_new = true
171
- assign(attrs)
172
- end
168
+ def initialize_from_database(attrs={})
169
+ @_new = false
170
+ load_from_database(attrs)
171
+ self
173
172
  end
174
173
 
175
174
  def persisted?
@@ -275,7 +274,7 @@ module MongoMapper
275
274
  unless attrs.nil?
276
275
  id_provided = attrs.keys.map { |k| k.to_s }.detect { |k| k == 'id' || k == '_id' }
277
276
  if !id_provided && self.class.can_default_id?
278
- write_key :_id, BSON::ObjectID.new
277
+ write_key :_id, BSON::ObjectId.new
279
278
  end
280
279
  end
281
280
  end
@@ -52,7 +52,7 @@ module MongoMapper
52
52
  hash[key] = value.map do |item|
53
53
  item.respond_to?(:as_json) ? item.as_json(options) : item
54
54
  end
55
- elsif value.is_a? BSON::ObjectID
55
+ elsif value.is_a? BSON::ObjectId
56
56
  hash[key] = value.to_s
57
57
  elsif value.respond_to?(:as_json)
58
58
  hash[key] = value.as_json(options)
@@ -60,7 +60,7 @@ module MongoMapper
60
60
  end
61
61
 
62
62
  # Replicate Rails 3 naming - and also bin anytihng after : for use in our dynamic classes from unit tests
63
- hash = { ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).gsub(/:.*/,'') => hash } if include_root_in_json
63
+ hash = { ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self.class.name)).gsub(/:.*/,'') => hash } if include_root_in_json
64
64
  hash
65
65
  end
66
66
  end
@@ -73,4 +73,4 @@ module MongoMapper
73
73
 
74
74
  end
75
75
  end
76
- end
76
+ end
@@ -21,8 +21,8 @@ module MongoMapper
21
21
 
22
22
  def valid?(instance)
23
23
  value = instance[attribute]
24
- return true if allow_blank && value.blank?
25
- return true if allow_nil && value.nil?
24
+ return allow_nil if value.nil? and not allow_nil.nil?
25
+ return allow_blank if value.blank? and not allow_blank.nil?
26
26
  base_conditions = case_sensitive ? {self.attribute => value} : {}
27
27
  doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
28
28
  doc.nil? || instance._id == doc._id
@@ -47,4 +47,4 @@ module MongoMapper
47
47
  end
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module MongoMapper
3
- Version = '0.8.3'
3
+ Version = '0.8.4'
4
4
  end
data/rails/init.rb ADDED
@@ -0,0 +1,19 @@
1
+ # See http://groups.google.com/group/mongomapper/browse_thread/thread/68f62e8eda43b43a/4841dba76938290c
2
+ #
3
+ # This is only for development mode. You will still want to clear the identity map before each request in production.
4
+ # See examples/identity_map for more on this.
5
+ #
6
+ # to_prepare is called before each request in development mode and the first request in production.
7
+ Rails.configuration.to_prepare do
8
+ if Rails.configuration.cache_classes
9
+ MongoMapper::Plugins::IdentityMap.clear
10
+ else
11
+ # Rails reloading was making descendants fill up and leak memory, these make sure they get cleared
12
+ MongoMapper::Document.descendants.each {|m| m.descendants.clear if m.respond_to?(:descendants) }
13
+ MongoMapper::Document.descendants.clear
14
+ MongoMapper::EmbeddedDocument.descendants.each {|m| m.descendants.clear if m.respond_to?(:descendants) }
15
+ MongoMapper::EmbeddedDocument.descendants.clear
16
+ MongoMapper::Plugins::IdentityMap.clear
17
+ MongoMapper::Plugins::IdentityMap.models.clear
18
+ end
19
+ end
@@ -44,7 +44,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
44
44
  end
45
45
 
46
46
  should "return nil if id set but document not found" do
47
- id = BSON::ObjectID.new
47
+ id = BSON::ObjectId.new
48
48
  @comment_class.new(:name => 'Foo', :post_id => id).post.nil?.should be_true
49
49
  end
50
50
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'test_helper.rb'
2
2
  require 'models'
3
3
 
4
4
  class ManyDocumentsProxyTest < Test::Unit::TestCase
@@ -145,6 +145,18 @@ class ManyDocumentsProxyTest < Test::Unit::TestCase
145
145
  project.save!
146
146
  status.should_not be_new
147
147
  end
148
+
149
+ should "not save the parent when building associations" do
150
+ project = Project.new
151
+ status = project.statuses.build(:name => 'Foo')
152
+ project.should be_new
153
+ end
154
+
155
+ should "not save the built object" do
156
+ project = Project.new
157
+ status = project.statuses.build(:name => 'Foo')
158
+ status.should be_new
159
+ end
148
160
  end
149
161
 
150
162
  context "create" do
@@ -232,6 +244,24 @@ class ManyDocumentsProxyTest < Test::Unit::TestCase
232
244
  end
233
245
  end
234
246
 
247
+ context "to_json" do
248
+ should "work on association" do
249
+ project = Project.create
250
+ 3.times { |i| project.statuses.create(:name => i.to_s) }
251
+
252
+ JSON.parse(project.statuses.to_json).collect{|status| status["name"] }.sort.should == ["0","1","2"]
253
+ end
254
+ end
255
+
256
+ context "as_json" do
257
+ should "work on association" do
258
+ project = Project.create
259
+ 3.times { |i| project.statuses.create(:name => i.to_s) }
260
+
261
+ project.statuses.as_json.collect{|status| status["name"] }.sort.should == ["0","1","2"]
262
+ end
263
+ end
264
+
235
265
  context "Unassociating documents" do
236
266
  setup do
237
267
  @project = Project.create
@@ -54,6 +54,20 @@ class OneEmbeddedProxyTest < Test::Unit::TestCase
54
54
  }.should_not raise_error
55
55
  end
56
56
 
57
+ should "load the parent and root documents for nested embedded documents" do
58
+ @address_class = EDoc('Address') do
59
+ key :city, String
60
+ key :state, String
61
+ end
62
+ @author_class.one :address, :class => @address_class
63
+ @post_class.one :author, :class => @author_class
64
+
65
+ post = @post_class.create(:title => 'Post Title', :author => { :name => 'Frank', :address => { :city => 'Boston', :state => 'MA' } })
66
+
67
+ post.author.address._parent_document.should == post.author
68
+ post.author.address._root_document.should == post
69
+ end
70
+
57
71
  should "have boolean method for testing presence" do
58
72
  @post_class.one :author, :class => @author_class
59
73
 
@@ -33,7 +33,7 @@ class CachingTest < Test::Unit::TestCase
33
33
 
34
34
  context "not new" do
35
35
  setup do
36
- @object_id = BSON::ObjectID.new
36
+ @object_id = BSON::ObjectId.new
37
37
  @doc = @klass.new
38
38
  @doc.stubs(:new?).returns(false)
39
39
  @doc.stubs(:id).returns(@object_id)
@@ -230,7 +230,7 @@ class DocumentTest < Test::Unit::TestCase
230
230
 
231
231
  context "database has keys not defined in model" do
232
232
  setup do
233
- @id = BSON::ObjectID.new
233
+ @id = BSON::ObjectId.new
234
234
  @document.collection.insert({
235
235
  :_id => @id,
236
236
  :first_name => 'John',
@@ -140,7 +140,7 @@ class IdentityMapTest < Test::Unit::TestCase
140
140
 
141
141
  context "#load" do
142
142
  setup do
143
- @id = BSON::ObjectID.new
143
+ @id = BSON::ObjectId.new
144
144
  end
145
145
 
146
146
  should "add document to map" do
@@ -327,7 +327,7 @@ class IdentityMapTest < Test::Unit::TestCase
327
327
 
328
328
  should "return nil for document id not found in collection" do
329
329
  assert_in_map(@person)
330
- @person_class.find_by_id(BSON::ObjectID.new).should be_nil
330
+ @person_class.find_by_id(BSON::ObjectId.new).should be_nil
331
331
  end
332
332
  end
333
333
 
@@ -348,7 +348,7 @@ class IdentityMapTest < Test::Unit::TestCase
348
348
  end
349
349
 
350
350
  should "return nil if not found" do
351
- @person_class.fields(:name).find(BSON::ObjectID.new).should be_nil
351
+ @person_class.fields(:name).find(BSON::ObjectId.new).should be_nil
352
352
  end
353
353
  end
354
354
 
@@ -452,7 +452,7 @@ class IdentityMapTest < Test::Unit::TestCase
452
452
 
453
453
  should "not add to map when loading" do
454
454
  @post_class.without_identity_map do
455
- post = @post_class.load({'_id' => BSON::ObjectID.new, 'title' => 'Awesome!'})
455
+ post = @post_class.load({'_id' => BSON::ObjectId.new, 'title' => 'Awesome!'})
456
456
  assert_not_in_map(post)
457
457
  end
458
458
  end
@@ -465,6 +465,14 @@ class IdentityMapTest < Test::Unit::TestCase
465
465
  loaded.should_not equal(post)
466
466
  end
467
467
  end
468
+
469
+ should "not load attributes from map when finding" do
470
+ post = @post_class.create(:title => 'Awesome!')
471
+ post.title = 'Temporary'
472
+ @post_class.without_identity_map do
473
+ @post_class.find(post.id).title.should == 'Awesome!'
474
+ end
475
+ end
468
476
 
469
477
  context "all" do
470
478
  should "not add to map" do
@@ -56,8 +56,8 @@ class QueryingTesting < Test::Unit::TestCase
56
56
  end
57
57
 
58
58
  should "automatically set id" do
59
- @doc.id.should be_instance_of(BSON::ObjectID)
60
- @doc._id.should be_instance_of(BSON::ObjectID)
59
+ @doc.id.should be_instance_of(BSON::ObjectId)
60
+ @doc._id.should be_instance_of(BSON::ObjectId)
61
61
  end
62
62
 
63
63
  should "no longer be new?" do
@@ -207,12 +207,12 @@ class QueryingTesting < Test::Unit::TestCase
207
207
  end
208
208
 
209
209
  should "compact not found when using find" do
210
- @document.find(@doc1._id, BSON::ObjectID.new.to_s).should == [@doc1]
210
+ @document.find(@doc1._id, BSON::ObjectId.new.to_s).should == [@doc1]
211
211
  end
212
212
 
213
213
  should "raise error if not all found when using find!" do
214
214
  assert_raises(MongoMapper::DocumentNotFound) do
215
- @document.find!(@doc1._id, BSON::ObjectID.new.to_s)
215
+ @document.find!(@doc1._id, BSON::ObjectId.new.to_s)
216
216
  end
217
217
  end
218
218
 
@@ -620,7 +620,7 @@ class QueryingTesting < Test::Unit::TestCase
620
620
  end
621
621
 
622
622
  should "assign an id for the document" do
623
- @doc.id.should be_instance_of(BSON::ObjectID)
623
+ @doc.id.should be_instance_of(BSON::ObjectId)
624
624
  end
625
625
 
626
626
  should "save attributes" do
@@ -688,7 +688,7 @@ class QueryingTesting < Test::Unit::TestCase
688
688
  end
689
689
 
690
690
  should "assign an id for the document" do
691
- @doc.id.should be_instance_of(BSON::ObjectID)
691
+ @doc.id.should be_instance_of(BSON::ObjectId)
692
692
  end
693
693
 
694
694
  should "save attributes" do
@@ -28,7 +28,7 @@ class StringIdCompatibilityTest < Test::Unit::TestCase
28
28
  project._id.should be_instance_of(String)
29
29
  project.id.size.should == 24
30
30
  lambda {
31
- BSON::ObjectID.from_string(project.id)
31
+ BSON::ObjectId.from_string(project.id)
32
32
  }.should_not raise_error
33
33
  end
34
34
 
data/test/test_helper.rb CHANGED
@@ -2,8 +2,8 @@ require 'rubygems'
2
2
  gem 'activesupport', ENV['ACTIVE_SUPPORT_VERSION']
3
3
  gem 'json'
4
4
  gem 'jnunemaker-matchy', '~> 0.4.0'
5
- gem 'shoulda', '~> 2.10.2'
6
- gem 'timecop', '~> 0.3.1'
5
+ gem 'shoulda', '~> 2.11'
6
+ gem 'timecop', '~> 0.3.5'
7
7
  gem 'mocha', '~> 0.9.8'
8
8
 
9
9
  $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
@@ -26,6 +26,9 @@ class JsonSerializationTest < Test::Unit::TestCase
26
26
  end
27
27
 
28
28
  def setup
29
+ Kernel.const_set('TopLevelContact', Doc('TopLevelContact'))
30
+ TopLevelContact.key :name, String
31
+
29
32
  Contact.include_root_in_json = false
30
33
  @contact = Contact.new(
31
34
  :name => 'Konata Izumi',
@@ -34,6 +37,18 @@ class JsonSerializationTest < Test::Unit::TestCase
34
37
  :awesome => true,
35
38
  :preferences => { :shows => 'anime' }
36
39
  )
40
+ @top_level_contact = TopLevelContact.new(
41
+ :name => 'Konata Izumi'
42
+ )
43
+ end
44
+
45
+ def teardown
46
+ Kernel.send(:remove_const, 'TopLevelContact') if Object.const_defined?('TopLevelContact')
47
+ end
48
+
49
+ should "include root for class with no module" do
50
+ TopLevelContact.include_root_in_json = true
51
+ assert_match %r{^\{"top_level_contact":\s?\{}, convert_to_json(@top_level_contact)
37
52
  end
38
53
 
39
54
  should "include demodulized root" do
@@ -31,7 +31,7 @@ class CloneTest < Test::Unit::TestCase
31
31
  end
32
32
 
33
33
  should "clone many embedded documents" do
34
- @doc.clone.widgets.should_not equal(@doc.widgets)
34
+ @doc.clone.widgets.object_id.should_not equal(@doc.widgets.object_id)
35
35
  end
36
36
 
37
37
  should "not be destroyed" do
@@ -105,7 +105,7 @@ class DocumentTest < Test::Unit::TestCase
105
105
  end
106
106
 
107
107
  should "create id during initialization" do
108
- @document.new._id.should be_instance_of(BSON::ObjectID)
108
+ @document.new._id.should be_instance_of(BSON::ObjectId)
109
109
  end
110
110
 
111
111
  should "have access to logger" do
@@ -165,7 +165,7 @@ class DocumentTest < Test::Unit::TestCase
165
165
 
166
166
  context "equality" do
167
167
  setup do
168
- @oid = BSON::ObjectID.new
168
+ @oid = BSON::ObjectId.new
169
169
  end
170
170
 
171
171
  should "delegate hash to _id" do
@@ -201,7 +201,7 @@ class DocumentTest < Test::Unit::TestCase
201
201
  end
202
202
 
203
203
  should "not be equal if class same but id different" do
204
- (@document.new('_id' => @oid) == @document.new('_id' => BSON::ObjectID.new)).should be(false)
204
+ (@document.new('_id' => @oid) == @document.new('_id' => BSON::ObjectId.new)).should be(false)
205
205
  end
206
206
 
207
207
  should "not be equal if id same but class different" do
@@ -236,17 +236,17 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
236
236
  end
237
237
 
238
238
  should "create id during initialization" do
239
- @document.new._id.should be_instance_of(BSON::ObjectID)
239
+ @document.new._id.should be_instance_of(BSON::ObjectId)
240
240
  end
241
241
 
242
242
  should "have id method returns _id" do
243
- id = BSON::ObjectID.new
243
+ id = BSON::ObjectId.new
244
244
  doc = @document.new(:_id => id)
245
245
  doc.id.should == id
246
246
  end
247
247
 
248
248
  should "convert string object id to mongo object id when assigning id with _id object id type" do
249
- id = BSON::ObjectID.new
249
+ id = BSON::ObjectId.new
250
250
  doc = @document.new(:id => id.to_s)
251
251
  doc._id.should == id
252
252
  doc.id.should == id
@@ -555,7 +555,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
555
555
 
556
556
  context "equality" do
557
557
  setup do
558
- @oid = BSON::ObjectID.new
558
+ @oid = BSON::ObjectId.new
559
559
  end
560
560
 
561
561
  should "delegate hash to _id" do
@@ -586,7 +586,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
586
586
  end
587
587
 
588
588
  should "not be equal if class same but id different" do
589
- (@document.new('_id' => @oid) == @document.new('_id' => BSON::ObjectID.new)).should be_false
589
+ (@document.new('_id' => @oid) == @document.new('_id' => BSON::ObjectId.new)).should be_false
590
590
  end
591
591
 
592
592
  should "not be equal if id same but class different" do
@@ -204,7 +204,7 @@ class SupportTest < Test::Unit::TestCase
204
204
  end
205
205
 
206
206
  should "return value if object id" do
207
- id = BSON::ObjectID.new
207
+ id = BSON::ObjectId.new
208
208
  ObjectId.to_mongo(id).should be(id)
209
209
  end
210
210
 
@@ -221,7 +221,7 @@ class SupportTest < Test::Unit::TestCase
221
221
  Object.from_mongo('21').should == '21'
222
222
  Object.from_mongo(9223372036854775807).should == 9223372036854775807
223
223
 
224
- id = BSON::ObjectID.new
224
+ id = BSON::ObjectId.new
225
225
  ObjectId.from_mongo(id).should == id
226
226
  end
227
227
  end
@@ -353,28 +353,28 @@ class SupportTest < Test::Unit::TestCase
353
353
  end
354
354
  end
355
355
 
356
- context "BSON::ObjectID" do
356
+ context "BSON::ObjectId" do
357
357
  context "#as_json" do
358
358
  should "convert object id to string" do
359
- id = BSON::ObjectID.new
359
+ id = BSON::ObjectId.new
360
360
  id.as_json.should == id.to_s
361
361
  end
362
362
  end
363
363
 
364
364
  context "#to_json" do
365
365
  should "convert object id to string" do
366
- id = BSON::ObjectID.new
366
+ id = BSON::ObjectId.new
367
367
  id.to_json.should == %Q("#{id}")
368
368
  end
369
369
 
370
370
  should "support ruby driver syntax also" do
371
- id = BSON::ObjectID.new
371
+ id = BSON::ObjectId.new
372
372
  id.original_to_json.should == %Q({"$oid": "#{id}"})
373
373
  end
374
374
  end
375
375
  end
376
376
 
377
- context "BSON::ObjectID.to_json" do
377
+ context "BSON::ObjectId.to_json" do
378
378
 
379
379
  end
380
380
  end
@@ -96,7 +96,7 @@ class KeyTest < Test::Unit::TestCase
96
96
  subject { @key }
97
97
 
98
98
  should "cast each element correctly" do
99
- ids = [BSON::ObjectID.new, BSON::ObjectID.new, BSON::ObjectID.new.to_s, BSON::ObjectID.new.to_s]
99
+ ids = [BSON::ObjectId.new, BSON::ObjectId.new, BSON::ObjectId.new.to_s, BSON::ObjectId.new.to_s]
100
100
  subject.set(ids).should == ids.map { |id| ObjectId.to_mongo(id) }
101
101
  end
102
102
  end
@@ -106,7 +106,7 @@ class KeyTest < Test::Unit::TestCase
106
106
  subject { @key }
107
107
 
108
108
  should "cast each element correctly" do
109
- ids = [BSON::ObjectID.new, BSON::ObjectID.new, BSON::ObjectID.new.to_s, BSON::ObjectID.new.to_s]
109
+ ids = [BSON::ObjectId.new, BSON::ObjectId.new, BSON::ObjectId.new.to_s, BSON::ObjectId.new.to_s]
110
110
  subject.set(ids).should == ids.map { |id| ObjectId.to_mongo(id) }
111
111
  end
112
112
  end
@@ -7,6 +7,26 @@ class ValidationsTest < Test::Unit::TestCase
7
7
  @document = Doc()
8
8
  end
9
9
 
10
+ context "Validating uniquness of" do
11
+ should "not validate nil when allow_nil false" do
12
+ @document.key :name, String
13
+ @document.validates_uniqueness_of :name, :allow_nil => false
14
+ doc = @document.new(:name => nil)
15
+ doc.should have_error_on(:name)
16
+ doc.name = "Ryan"
17
+ doc.should_not have_error_on(:name)
18
+ end
19
+
20
+ should "not validate blank when allow_blank false" do
21
+ @document.key :name, String
22
+ @document.validates_uniqueness_of :name, :allow_blank => false
23
+ doc = @document.new(:name => "")
24
+ doc.should have_error_on(:name)
25
+ doc.name = "Ryan"
26
+ doc.should_not have_error_on(:name)
27
+ end
28
+ end
29
+
10
30
  context "Validating acceptance of" do
11
31
  should "work with validates_acceptance_of macro" do
12
32
  @document.key :terms, String
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 57
4
+ hash: 55
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 8
9
- - 3
10
- version: 0.8.3
9
+ - 4
10
+ version: 0.8.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Nunemaker
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-09 00:00:00 -04:00
18
+ date: 2010-08-29 00:00:00 -04:00
19
19
  default_executable: mmconsole
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -58,12 +58,12 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- hash: 21
61
+ hash: 25
62
62
  segments:
63
63
  - 0
64
64
  - 3
65
- - 3
66
- version: 0.3.3
65
+ - 5
66
+ version: 0.3.5
67
67
  type: :runtime
68
68
  version_requirements: *id003
69
69
  - !ruby/object:Gem::Dependency
@@ -118,12 +118,11 @@ dependencies:
118
118
  requirements:
119
119
  - - ~>
120
120
  - !ruby/object:Gem::Version
121
- hash: 35
121
+ hash: 21
122
122
  segments:
123
123
  - 2
124
- - 10
125
- - 2
126
- version: 2.10.2
124
+ - 11
125
+ version: "2.11"
127
126
  type: :development
128
127
  version_requirements: *id007
129
128
  - !ruby/object:Gem::Dependency
@@ -169,11 +168,19 @@ extra_rdoc_files: []
169
168
 
170
169
  files:
171
170
  - bin/mmconsole
171
+ - examples/attr_accessible.rb
172
+ - examples/attr_protected.rb
173
+ - examples/cache_key.rb
174
+ - examples/custom_types.rb
175
+ - examples/identity_map/automatic.rb
176
+ - examples/identity_map/middleware.rb
177
+ - examples/identity_map.rb
172
178
  - examples/keys.rb
173
179
  - examples/modifiers/set.rb
174
180
  - examples/plugins.rb
175
181
  - examples/querying.rb
176
182
  - examples/scopes.rb
183
+ - examples/validating/embedded_docs.rb
177
184
  - lib/mongo_mapper/connection.rb
178
185
  - lib/mongo_mapper/document.rb
179
186
  - lib/mongo_mapper/embedded_document.rb
@@ -243,6 +250,7 @@ files:
243
250
  - lib/mongo_mapper/support/descendant_appends.rb
244
251
  - lib/mongo_mapper/version.rb
245
252
  - lib/mongo_mapper.rb
253
+ - rails/init.rb
246
254
  - test/_NOTE_ON_TESTING
247
255
  - test/functional/associations/test_belongs_to_polymorphic_proxy.rb
248
256
  - test/functional/associations/test_belongs_to_proxy.rb
@@ -300,6 +308,7 @@ files:
300
308
  - test/unit/test_time_zones.rb
301
309
  - test/unit/test_validations.rb
302
310
  - LICENSE
311
+ - UPGRADES
303
312
  - README.rdoc
304
313
  has_rdoc: true
305
314
  homepage: http://github.com/jnunemaker/mongomapper