mongo_mapper-unstable 2009.11.8 → 2009.11.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/Rakefile +3 -3
  2. data/VERSION +1 -1
  3. data/bin/mmconsole +10 -5
  4. data/lib/mongo_mapper.rb +28 -5
  5. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +1 -1
  6. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +1 -1
  7. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +2 -2
  8. data/lib/mongo_mapper/associations/many_documents_proxy.rb +2 -2
  9. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +2 -1
  10. data/lib/mongo_mapper/document.rb +3 -12
  11. data/lib/mongo_mapper/embedded_document.rb +37 -19
  12. data/lib/mongo_mapper/finder_options.rb +17 -11
  13. data/lib/mongo_mapper/rails_compatibility/document.rb +4 -0
  14. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +4 -0
  15. data/lib/mongo_mapper/serializers/json_serializer.rb +2 -2
  16. data/lib/mongo_mapper/support.rb +16 -44
  17. data/lib/mongo_mapper/types.rb +64 -0
  18. data/lib/mongo_mapper/validations.rb +1 -1
  19. data/mongo_mapper.gemspec +15 -12
  20. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +10 -10
  21. data/test/functional/associations/test_belongs_to_proxy.rb +2 -1
  22. data/test/functional/associations/test_many_documents_as_proxy.rb +13 -12
  23. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +34 -34
  24. data/test/functional/associations/test_many_embedded_proxy.rb +22 -22
  25. data/test/functional/associations/test_many_polymorphic_proxy.rb +10 -10
  26. data/test/functional/associations/test_many_proxy.rb +14 -15
  27. data/test/functional/test_associations.rb +4 -4
  28. data/test/functional/test_binary.rb +1 -1
  29. data/test/functional/test_dirty.rb +6 -6
  30. data/test/functional/test_document.rb +64 -65
  31. data/test/functional/test_embedded_document.rb +34 -14
  32. data/test/functional/test_string_id_compatibility.rb +72 -0
  33. data/test/functional/test_validations.rb +1 -1
  34. data/test/models.rb +24 -24
  35. data/test/unit/test_document.rb +7 -4
  36. data/test/unit/test_embedded_document.rb +47 -5
  37. data/test/unit/test_finder_options.rb +22 -3
  38. data/test/unit/test_mongo_mapper.rb +65 -0
  39. data/test/unit/test_rails_compatibility.rb +14 -0
  40. data/test/unit/test_support.rb +45 -0
  41. metadata +8 -5
  42. data/test/unit/test_mongomapper.rb +0 -28
@@ -51,7 +51,7 @@ module MongoMapper #:nodoc:
51
51
  # "permalink": "1-konata-izumi"}
52
52
  def to_json(options={})
53
53
  apply_to_json_defaults(options)
54
-
54
+
55
55
  if include_root_in_json
56
56
  "{#{self.class.json_class_name}: #{JsonSerializer.new(self, options).to_s}}"
57
57
  else
@@ -75,7 +75,7 @@ module MongoMapper #:nodoc:
75
75
  @json_class_name ||= name.demodulize.underscore.inspect
76
76
  end
77
77
  end
78
-
78
+
79
79
  private
80
80
  def apply_to_json_defaults(options)
81
81
  unless options[:only]
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  class BasicObject #:nodoc:
2
4
  instance_methods.each { |m| undef_method m unless m =~ /(^__|instance_eval)/ }
3
5
  end unless defined?(BasicObject)
@@ -13,34 +15,6 @@ class Array
13
15
  end
14
16
  end
15
17
 
16
- class Binary
17
- def self.to_mongo(value)
18
- if value.is_a?(ByteBuffer)
19
- value
20
- else
21
- value.nil? ? nil : ByteBuffer.new(value)
22
- end
23
- end
24
-
25
- def self.from_mongo(value)
26
- value
27
- end
28
- end
29
-
30
- class Boolean
31
- def self.to_mongo(value)
32
- if value.is_a?(Boolean)
33
- value
34
- else
35
- ['true', 't', '1'].include?(value.to_s.downcase)
36
- end
37
- end
38
-
39
- def self.from_mongo(value)
40
- !!value
41
- end
42
- end
43
-
44
18
  class Date
45
19
  def self.to_mongo(value)
46
20
  date = Date.parse(value.to_s)
@@ -120,6 +94,16 @@ class Object
120
94
  end
121
95
  end
122
96
 
97
+ class Set
98
+ def self.to_mongo(value)
99
+ value.to_a
100
+ end
101
+
102
+ def self.from_mongo(value)
103
+ Set.new(value || [])
104
+ end
105
+ end
106
+
123
107
  class String
124
108
  def self.to_mongo(value)
125
109
  value.nil? ? nil : value.to_s
@@ -138,33 +122,21 @@ class Symbol
138
122
  end
139
123
  end
140
124
 
141
- class Time
125
+ class Time
142
126
  def self.to_mongo(value)
143
127
  if value.nil? || value == ''
144
128
  nil
145
129
  else
146
- to_utc_time(value)
130
+ time = MongoMapper.time_class.parse(value.to_s)
131
+ time && time.utc
147
132
  end
148
133
  end
149
134
 
150
135
  def self.from_mongo(value)
151
- if Time.respond_to?(:zone) && Time.zone && value.present?
136
+ if MongoMapper.use_time_zone? && value.present?
152
137
  value.in_time_zone(Time.zone)
153
138
  else
154
139
  value
155
140
  end
156
141
  end
157
-
158
- def self.to_utc_time(value)
159
- to_local_time(value).try(:utc)
160
- end
161
-
162
- # make sure we have a time and that it is local
163
- def self.to_local_time(value)
164
- if Time.respond_to?(:zone) && Time.zone
165
- Time.zone.parse(value.to_s)
166
- else
167
- Time.parse(value.to_s)
168
- end
169
- end
170
142
  end
@@ -0,0 +1,64 @@
1
+ module MongoMapper
2
+ module Types
3
+ class Binary
4
+ def self.to_mongo(value)
5
+ if value.is_a?(ByteBuffer)
6
+ value
7
+ else
8
+ value.nil? ? nil : ByteBuffer.new(value)
9
+ end
10
+ end
11
+
12
+ def self.from_mongo(value)
13
+ value
14
+ end
15
+ end
16
+
17
+ class Boolean
18
+ def self.to_mongo(value)
19
+ if value.is_a?(Boolean)
20
+ value
21
+ else
22
+ ['true', 't', '1'].include?(value.to_s.downcase)
23
+ end
24
+ end
25
+
26
+ def self.from_mongo(value)
27
+ !!value
28
+ end
29
+ end
30
+
31
+ class ObjectId
32
+ def self.to_mongo(value)
33
+ if value.nil?
34
+ nil
35
+ elsif value.is_a?(Mongo::ObjectID)
36
+ value
37
+ else
38
+ Mongo::ObjectID.from_string(value.to_s)
39
+ end
40
+ end
41
+
42
+ def self.from_mongo(value)
43
+ value
44
+ end
45
+ end
46
+
47
+ # This allows using just Boolean when defining
48
+ # keys instead of MongoMapper::Types::Boolean
49
+ module Lookup
50
+ def const_missing(name)
51
+ if MongoMapper::Types.const_defined?(name)
52
+ MongoMapper::Types.const_get(name)
53
+ else
54
+ super
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # This was required to get in front of ActiveSupports Class#const_missing
62
+ Class.instance_eval do
63
+ include MongoMapper::Types::Lookup
64
+ end
@@ -15,7 +15,7 @@ module MongoMapper
15
15
  return true if allow_blank && value.blank?
16
16
  base_conditions = case_sensitive ? {self.attribute => value} : {}
17
17
  doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
18
- doc.nil? || instance.id == doc.id
18
+ doc.nil? || instance._id == doc._id
19
19
  end
20
20
 
21
21
  def message(instance)
data/mongo_mapper.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_mapper}
8
- s.version = "0.5.8"
8
+ s.version = "0.6.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Nunemaker"]
12
- s.date = %q{2009-10-29}
12
+ s.date = %q{2009-11-17}
13
13
  s.default_executable = %q{mmconsole}
14
14
  s.email = %q{nunemaker@gmail.com}
15
15
  s.executables = ["mmconsole"]
@@ -50,6 +50,7 @@ Gem::Specification.new do |s|
50
50
  "lib/mongo_mapper/serialization.rb",
51
51
  "lib/mongo_mapper/serializers/json_serializer.rb",
52
52
  "lib/mongo_mapper/support.rb",
53
+ "lib/mongo_mapper/types.rb",
53
54
  "lib/mongo_mapper/validations.rb",
54
55
  "mongo_mapper.gemspec",
55
56
  "specs.watchr",
@@ -70,6 +71,7 @@ Gem::Specification.new do |s|
70
71
  "test/functional/test_logger.rb",
71
72
  "test/functional/test_pagination.rb",
72
73
  "test/functional/test_rails_compatibility.rb",
74
+ "test/functional/test_string_id_compatibility.rb",
73
75
  "test/functional/test_validations.rb",
74
76
  "test/models.rb",
75
77
  "test/support/custom_matchers.rb",
@@ -82,7 +84,7 @@ Gem::Specification.new do |s|
82
84
  "test/unit/test_embedded_document.rb",
83
85
  "test/unit/test_finder_options.rb",
84
86
  "test/unit/test_key.rb",
85
- "test/unit/test_mongomapper.rb",
87
+ "test/unit/test_mongo_mapper.rb",
86
88
  "test/unit/test_observing.rb",
87
89
  "test/unit/test_pagination.rb",
88
90
  "test/unit/test_rails_compatibility.rb",
@@ -113,6 +115,7 @@ Gem::Specification.new do |s|
113
115
  "test/functional/test_logger.rb",
114
116
  "test/functional/test_pagination.rb",
115
117
  "test/functional/test_rails_compatibility.rb",
118
+ "test/functional/test_string_id_compatibility.rb",
116
119
  "test/functional/test_validations.rb",
117
120
  "test/models.rb",
118
121
  "test/support/custom_matchers.rb",
@@ -125,7 +128,7 @@ Gem::Specification.new do |s|
125
128
  "test/unit/test_embedded_document.rb",
126
129
  "test/unit/test_finder_options.rb",
127
130
  "test/unit/test_key.rb",
128
- "test/unit/test_mongomapper.rb",
131
+ "test/unit/test_mongo_mapper.rb",
129
132
  "test/unit/test_observing.rb",
130
133
  "test/unit/test_pagination.rb",
131
134
  "test/unit/test_rails_compatibility.rb",
@@ -141,29 +144,29 @@ Gem::Specification.new do |s|
141
144
 
142
145
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
143
146
  s.add_runtime_dependency(%q<activesupport>, [">= 2.3"])
144
- s.add_runtime_dependency(%q<mongo>, ["= 0.16"])
147
+ s.add_runtime_dependency(%q<mongo>, ["= 0.17.1"])
145
148
  s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
146
149
  s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
147
150
  s.add_development_dependency(%q<shoulda>, ["= 2.10.2"])
148
151
  s.add_development_dependency(%q<timecop>, ["= 0.3.1"])
149
- s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
152
+ s.add_development_dependency(%q<mocha>, ["= 0.9.8"])
150
153
  else
151
154
  s.add_dependency(%q<activesupport>, [">= 2.3"])
152
- s.add_dependency(%q<mongo>, ["= 0.16"])
153
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
155
+ s.add_dependency(%q<mongo>, ["= 0.17.1"])
156
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
154
157
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
155
158
  s.add_dependency(%q<shoulda>, ["= 2.10.2"])
156
159
  s.add_dependency(%q<timecop>, ["= 0.3.1"])
157
- s.add_dependency(%q<mocha>, ["= 0.9.4"])
160
+ s.add_dependency(%q<mocha>, ["= 0.9.8"])
158
161
  end
159
162
  else
160
163
  s.add_dependency(%q<activesupport>, [">= 2.3"])
161
- s.add_dependency(%q<mongo>, ["= 0.16"])
162
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.0"])
164
+ s.add_dependency(%q<mongo>, ["= 0.17.1"])
165
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.8.1"])
163
166
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
164
167
  s.add_dependency(%q<shoulda>, ["= 2.10.2"])
165
168
  s.add_dependency(%q<timecop>, ["= 0.3.1"])
166
- s.add_dependency(%q<mocha>, ["= 0.9.4"])
169
+ s.add_dependency(%q<mocha>, ["= 0.9.8"])
167
170
  end
168
171
  end
169
172
 
@@ -19,11 +19,11 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
19
19
  status.target = project
20
20
  status.save.should be_true
21
21
 
22
- from_db = Status.find(status.id)
23
- from_db.target.nil?.should be_false
24
- from_db.target_id.should == project.id
25
- from_db.target_type.should == "Project"
26
- from_db.target.name.should == "mongomapper"
22
+ status = status.reload
23
+ status.target.nil?.should be_false
24
+ status.target_id.should == project._id
25
+ status.target_type.should == "Project"
26
+ status.target.name.should == "mongomapper"
27
27
  end
28
28
 
29
29
  should "unset the association" do
@@ -32,11 +32,11 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
32
32
  status.target = project
33
33
  status.save.should be_true
34
34
 
35
- from_db = Status.find(status.id)
36
- from_db.target = nil
37
- from_db.target_type.nil?.should be_true
38
- from_db.target_id.nil?.should be_true
39
- from_db.target.nil?.should be_true
35
+ status = status.reload
36
+ status.target = nil
37
+ status.target_type.nil?.should be_true
38
+ status.target_id.nil?.should be_true
39
+ status.target.nil?.should be_true
40
40
  end
41
41
 
42
42
  context "association id set but document not found" do
@@ -42,6 +42,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
42
42
  end
43
43
 
44
44
  should "return nil if id set but document not found" do
45
- @comment_class.new(:name => 'Foo', :post_id => '1234').post.nil?.should be_true
45
+ id = Mongo::ObjectID.new
46
+ @comment_class.new(:name => 'Foo', :post_id => id).post.nil?.should be_true
46
47
  end
47
48
  end
@@ -35,19 +35,20 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
35
35
  PostComment.new(:body => 'baz')
36
36
  ]
37
37
  }.should change { PostComment.count }.by(3)
38
-
39
- from_db = Post.find(post.id)
40
- from_db.comments.size.should == 3
41
- from_db.comments[0].body.should == 'foo'
42
- from_db.comments[1].body.should == 'bar'
43
- from_db.comments[2].body.should == 'baz'
38
+
39
+ post = post.reload
40
+ post.comments.size.should == 3
41
+ bodies = post.comments.collect(&:body)
42
+ bodies.should include('foo')
43
+ bodies.should include('bar')
44
+ bodies.should include('baz')
44
45
  end
45
46
 
46
47
  context "build" do
47
48
  should "assign foreign key" do
48
49
  post = Post.new
49
50
  comment = post.comments.build
50
- comment.commentable_id.should == post.id
51
+ comment.commentable_id.should == post._id
51
52
  end
52
53
 
53
54
  should "assign _type" do
@@ -67,7 +68,7 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
67
68
  should "assign foreign key" do
68
69
  post = Post.new
69
70
  comment = post.comments.create
70
- comment.commentable_id.should == post.id
71
+ comment.commentable_id.should == post._id
71
72
  end
72
73
 
73
74
  should "assign _type" do
@@ -166,25 +167,25 @@ class ManyDocumentsAsProxyTest < Test::Unit::TestCase
166
167
 
167
168
  context "with one id" do
168
169
  should "work for id in association" do
169
- @post.comments.find(@comment2.id).should == @comment2
170
+ @post.comments.find(@comment2._id).should == @comment2
170
171
  end
171
172
 
172
173
  should "not work for id not in association" do
173
174
  lambda {
174
- @post.comments.find!(@comment5.id)
175
+ @post.comments.find!(@comment5._id)
175
176
  }.should raise_error(MongoMapper::DocumentNotFound)
176
177
  end
177
178
  end
178
179
 
179
180
  context "with multiple ids" do
180
181
  should "work for ids in association" do
181
- posts = @post.comments.find!(@comment1.id, @comment2.id)
182
+ posts = @post.comments.find!(@comment1._id, @comment2._id)
182
183
  posts.should == [@comment1, @comment2]
183
184
  end
184
185
 
185
186
  should "not work for ids not in association" do
186
187
  lambda {
187
- @post.comments.find!(@comment1.id, @comment2.id, @comment4.id)
188
+ @post.comments.find!(@comment1._id, @comment2._id, @comment4._id)
188
189
  }.should raise_error(MongoMapper::DocumentNotFound)
189
190
  end
190
191
  end
@@ -24,9 +24,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
24
24
  catalog.medias = [Video.new("file" => "video.mpg", "length" => 3600)]
25
25
  catalog.save.should be_true
26
26
 
27
- from_db = Catalog.find(catalog.id)
28
- from_db.medias.size.should == 1
29
- from_db.medias[0].file.should == "video.mpg"
27
+ catalog = catalog.reload
28
+ catalog.medias.size.should == 1
29
+ catalog.medias[0].file.should == "video.mpg"
30
30
  end
31
31
 
32
32
  should "store different associations" do
@@ -38,15 +38,15 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
38
38
  ]
39
39
  catalog.save.should be_true
40
40
 
41
- from_db = Catalog.find(catalog.id)
42
- from_db.medias.size.should == 3
43
- from_db.medias[0].file.should == "video.mpg"
44
- from_db.medias[0].length.should == 3600
45
- from_db.medias[1].file.should == "music.mp3"
46
- from_db.medias[1].bitrate.should == "128kbps"
47
- from_db.medias[2].file.should == "image.png"
48
- from_db.medias[2].width.should == 800
49
- from_db.medias[2].height.should == 600
41
+ catalog = catalog.reload
42
+ catalog.medias.size.should == 3
43
+ catalog.medias[0].file.should == "video.mpg"
44
+ catalog.medias[0].length.should == 3600
45
+ catalog.medias[1].file.should == "music.mp3"
46
+ catalog.medias[1].bitrate.should == "128kbps"
47
+ catalog.medias[2].file.should == "image.png"
48
+ catalog.medias[2].width.should == 800
49
+ catalog.medias[2].height.should == 600
50
50
  end
51
51
 
52
52
  context "With modularized models" do
@@ -75,16 +75,16 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
75
75
  fleet.transports[2].year.should == 2008
76
76
  fleet.save.should be_true
77
77
 
78
- from_db = TrModels::Fleet.find(fleet.id)
79
- from_db.transports.size.should == 3
80
- from_db.transports[0].license_plate.should == "GGG123"
81
- from_db.transports[0].icu.should be_true
82
- from_db.transports[1].license_plate.should == "ABC123"
83
- from_db.transports[1].model.should == "VW Golf"
84
- from_db.transports[1].year.should == 2001
85
- from_db.transports[2].license_plate.should == "DEF123"
86
- from_db.transports[2].model.should == "Honda Accord"
87
- from_db.transports[2].year.should == 2008
78
+ fleet = fleet.reload
79
+ fleet.transports.size.should == 3
80
+ fleet.transports[0].license_plate.should == "GGG123"
81
+ fleet.transports[0].icu.should be_true
82
+ fleet.transports[1].license_plate.should == "ABC123"
83
+ fleet.transports[1].model.should == "VW Golf"
84
+ fleet.transports[1].year.should == 2001
85
+ fleet.transports[2].license_plate.should == "DEF123"
86
+ fleet.transports[2].model.should == "Honda Accord"
87
+ fleet.transports[2].year.should == 2008
88
88
  end
89
89
 
90
90
  should "default reader to empty array" do
@@ -104,9 +104,9 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
104
104
  fleet.transports = [TrModels::Car.new("license_plate" => "DCU2013", "model" => "Honda Civic")]
105
105
  fleet.save.should be_true
106
106
 
107
- from_db = TrModels::Fleet.find(fleet.id)
108
- from_db.transports.size.should == 1
109
- from_db.transports[0].license_plate.should == "DCU2013"
107
+ fleet = fleet.reload
108
+ fleet.transports.size.should == 1
109
+ fleet.transports[0].license_plate.should == "DCU2013"
110
110
  end
111
111
 
112
112
  should "store different associations" do
@@ -118,15 +118,15 @@ class ManyEmbeddedPolymorphicProxyTest < Test::Unit::TestCase
118
118
  ]
119
119
  fleet.save.should be_true
120
120
 
121
- from_db = TrModels::Fleet.find(fleet.id)
122
- from_db.transports.size.should == 3
123
- from_db.transports[0].license_plate.should == "ABC1223"
124
- from_db.transports[0].model.should == "Honda Civic"
125
- from_db.transports[0].year.should == 2003
126
- from_db.transports[1].license_plate.should == "XYZ9090"
127
- from_db.transports[1].max_passengers.should == 51
128
- from_db.transports[2].license_plate.should == "HDD3030"
129
- from_db.transports[2].icu.should == true
121
+ fleet = fleet.reload
122
+ fleet.transports.size.should == 3
123
+ fleet.transports[0].license_plate.should == "ABC1223"
124
+ fleet.transports[0].model.should == "Honda Civic"
125
+ fleet.transports[0].year.should == 2003
126
+ fleet.transports[1].license_plate.should == "XYZ9090"
127
+ fleet.transports[1].max_passengers.should == 51
128
+ fleet.transports[2].license_plate.should == "HDD3030"
129
+ fleet.transports[2].icu.should == true
130
130
  end
131
131
  end
132
132