mongo_mapper-unstable 2010.2.27 → 2010.2.28
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/mongo_mapper/document.rb +13 -2
- data/lib/mongo_mapper/embedded_document.rb +6 -1
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +1 -12
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +1 -1
- data/lib/mongo_mapper/plugins/callbacks.rb +163 -10
- data/lib/mongo_mapper/plugins/keys.rb +8 -1
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +7 -3
- data/lib/mongo_mapper/query.rb +1 -1
- data/lib/mongo_mapper.rb +27 -8
- data/test/functional/test_document.rb +76 -39
- data/test/functional/test_embedded_document.rb +23 -23
- data/test/support/timing.rb +1 -1
- data/test/test_helper.rb +4 -0
- data/test/unit/test_embedded_document.rb +15 -15
- data/test/unit/test_keys.rb +15 -11
- data/test/unit/test_mongo_mapper.rb +31 -1
- data/test/unit/test_pagination.rb +33 -0
- data/test/unit/test_query.rb +6 -0
- data/test/unit/test_support.rb +9 -5
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2010.02.
|
1
|
+
2010.02.28
|
@@ -23,7 +23,7 @@ module MongoMapper
|
|
23
23
|
plugin Plugins::Serialization
|
24
24
|
plugin Plugins::Validations
|
25
25
|
plugin Plugins::Callbacks # for now callbacks needs to be after validations
|
26
|
-
|
26
|
+
|
27
27
|
extend Plugins::Validations::DocumentMacros
|
28
28
|
end
|
29
29
|
|
@@ -200,7 +200,7 @@ module MongoMapper
|
|
200
200
|
def set_database_name(name)
|
201
201
|
@database_name = name
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
def database_name
|
205
205
|
@database_name
|
206
206
|
end
|
@@ -374,9 +374,14 @@ module MongoMapper
|
|
374
374
|
end
|
375
375
|
|
376
376
|
def delete
|
377
|
+
@_destroyed = true
|
377
378
|
self.class.delete(id) unless new?
|
378
379
|
end
|
379
380
|
|
381
|
+
def destroyed?
|
382
|
+
@_destroyed == true
|
383
|
+
end
|
384
|
+
|
380
385
|
def reload
|
381
386
|
if attrs = collection.find_one({:_id => _id})
|
382
387
|
self.class.associations.each { |name, assoc| send(name).reset if respond_to?(name) }
|
@@ -387,6 +392,12 @@ module MongoMapper
|
|
387
392
|
end
|
388
393
|
end
|
389
394
|
|
395
|
+
# Used by embedded docs to find root easily without if/respond_to? stuff.
|
396
|
+
# Documents are always root documents.
|
397
|
+
def _root_document
|
398
|
+
self
|
399
|
+
end
|
400
|
+
|
390
401
|
private
|
391
402
|
def create_or_update(options={})
|
392
403
|
result = new? ? create(options) : update(options)
|
@@ -20,7 +20,7 @@ module MongoMapper
|
|
20
20
|
plugin Plugins::Serialization
|
21
21
|
plugin Plugins::Validations
|
22
22
|
|
23
|
-
|
23
|
+
attr_reader :_root_document, :_parent_document
|
24
24
|
end
|
25
25
|
|
26
26
|
super
|
@@ -50,6 +50,11 @@ module MongoMapper
|
|
50
50
|
end
|
51
51
|
result
|
52
52
|
end
|
53
|
+
|
54
|
+
def _parent_document=(value)
|
55
|
+
@_root_document = value._root_document
|
56
|
+
@_parent_document = value
|
57
|
+
end
|
53
58
|
end # InstanceMethods
|
54
59
|
end # EmbeddedDocument
|
55
60
|
end # MongoMapper
|
@@ -30,19 +30,8 @@ module MongoMapper
|
|
30
30
|
alias_method :concat, :<<
|
31
31
|
|
32
32
|
private
|
33
|
-
def _root_document
|
34
|
-
if owner.respond_to?(:_root_document)
|
35
|
-
owner._root_document
|
36
|
-
else
|
37
|
-
owner
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
33
|
def assign_references(*docs)
|
42
|
-
docs.each
|
43
|
-
doc._root_document = _root_document
|
44
|
-
doc._parent_document = owner
|
45
|
-
end
|
34
|
+
docs.each { |doc| doc._parent_document = owner }
|
46
35
|
end
|
47
36
|
end
|
48
37
|
end
|
@@ -1,22 +1,50 @@
|
|
1
|
+
# Almost all of this callback stuff is pulled directly from ActiveSupport
|
2
|
+
# in the interest of support rails 2 and 3 at the same time and is the
|
3
|
+
# same copyright as rails.
|
1
4
|
module MongoMapper
|
2
5
|
module Plugins
|
3
6
|
module Callbacks
|
4
7
|
def self.configure(model)
|
5
8
|
model.class_eval do
|
6
|
-
include ActiveSupport::Callbacks
|
7
|
-
|
8
9
|
define_callbacks(
|
9
|
-
:before_save,
|
10
|
-
:before_create,
|
11
|
-
:before_update,
|
12
|
-
:before_validation,
|
13
|
-
:before_validation_on_create, :after_validation_on_create,
|
14
|
-
:before_validation_on_update, :after_validation_on_update,
|
15
|
-
:before_destroy,
|
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
|
16
17
|
)
|
17
18
|
end
|
18
19
|
end
|
19
|
-
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def define_callbacks(*callbacks)
|
23
|
+
callbacks.each do |callback|
|
24
|
+
class_eval <<-"end_eval"
|
25
|
+
def self.#{callback}(*methods, &block)
|
26
|
+
callbacks = CallbackChain.build(:#{callback}, *methods, &block)
|
27
|
+
@#{callback}_callbacks ||= CallbackChain.new
|
28
|
+
@#{callback}_callbacks.concat callbacks
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.#{callback}_callback_chain
|
32
|
+
@#{callback}_callbacks ||= CallbackChain.new
|
33
|
+
|
34
|
+
if superclass.respond_to?(:#{callback}_callback_chain)
|
35
|
+
CallbackChain.new(
|
36
|
+
superclass.#{callback}_callback_chain +
|
37
|
+
@#{callback}_callbacks
|
38
|
+
)
|
39
|
+
else
|
40
|
+
@#{callback}_callbacks
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end_eval
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
20
48
|
module InstanceMethods
|
21
49
|
def valid?
|
22
50
|
action = new? ? 'create' : 'update'
|
@@ -37,6 +65,10 @@ module MongoMapper
|
|
37
65
|
result
|
38
66
|
end
|
39
67
|
|
68
|
+
def run_callbacks(kind, options = {}, &block)
|
69
|
+
self.class.send("#{kind}_callback_chain").run(self, options, &block)
|
70
|
+
end
|
71
|
+
|
40
72
|
private
|
41
73
|
def create_or_update(*args)
|
42
74
|
run_callbacks(:before_save)
|
@@ -60,6 +92,127 @@ module MongoMapper
|
|
60
92
|
result
|
61
93
|
end
|
62
94
|
end
|
95
|
+
|
96
|
+
class CallbackChain < Array
|
97
|
+
def self.build(kind, *methods, &block)
|
98
|
+
methods, options = extract_options(*methods, &block)
|
99
|
+
methods.map! { |method| Callback.new(kind, method, options) }
|
100
|
+
new(methods)
|
101
|
+
end
|
102
|
+
|
103
|
+
def run(object, options = {}, &terminator)
|
104
|
+
enumerator = options[:enumerator] || :each
|
105
|
+
|
106
|
+
unless block_given?
|
107
|
+
send(enumerator) { |callback| callback.call(object) }
|
108
|
+
else
|
109
|
+
send(enumerator) do |callback|
|
110
|
+
result = callback.call(object)
|
111
|
+
break result if terminator.call(result, object)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# TODO: Decompose into more Array like behavior
|
117
|
+
def replace_or_append!(chain)
|
118
|
+
if index = index(chain)
|
119
|
+
self[index] = chain
|
120
|
+
else
|
121
|
+
self << chain
|
122
|
+
end
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
def find(callback, &block)
|
127
|
+
select { |c| c == callback && (!block_given? || yield(c)) }.first
|
128
|
+
end
|
129
|
+
|
130
|
+
def delete(callback)
|
131
|
+
super(callback.is_a?(Callback) ? callback : find(callback))
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
def self.extract_options(*methods, &block)
|
136
|
+
methods.flatten!
|
137
|
+
options = methods.extract_options!
|
138
|
+
methods << block if block_given?
|
139
|
+
return methods, options
|
140
|
+
end
|
141
|
+
|
142
|
+
def extract_options(*methods, &block)
|
143
|
+
self.class.extract_options(*methods, &block)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class Callback
|
148
|
+
attr_reader :kind, :method, :identifier, :options
|
149
|
+
|
150
|
+
def initialize(kind, method, options = {})
|
151
|
+
@kind = kind
|
152
|
+
@method = method
|
153
|
+
@identifier = options[:identifier]
|
154
|
+
@options = options
|
155
|
+
end
|
156
|
+
|
157
|
+
def ==(other)
|
158
|
+
case other
|
159
|
+
when Callback
|
160
|
+
(self.identifier && self.identifier == other.identifier) || self.method == other.method
|
161
|
+
else
|
162
|
+
(self.identifier && self.identifier == other) || self.method == other
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def eql?(other)
|
167
|
+
self == other
|
168
|
+
end
|
169
|
+
|
170
|
+
def dup
|
171
|
+
self.class.new(@kind, @method, @options.dup)
|
172
|
+
end
|
173
|
+
|
174
|
+
def hash
|
175
|
+
if @identifier
|
176
|
+
@identifier.hash
|
177
|
+
else
|
178
|
+
@method.hash
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def call(*args, &block)
|
183
|
+
evaluate_method(method, *args, &block) if should_run_callback?(*args)
|
184
|
+
rescue LocalJumpError
|
185
|
+
raise ArgumentError,
|
186
|
+
"Cannot yield from a Proc type filter. The Proc must take two " +
|
187
|
+
"arguments and execute #call on the second argument."
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
def evaluate_method(method, *args, &block)
|
192
|
+
case method
|
193
|
+
when Symbol
|
194
|
+
object = args.shift
|
195
|
+
object.send(method, *args, &block)
|
196
|
+
when String
|
197
|
+
eval(method, args.first.instance_eval { binding })
|
198
|
+
when Proc, Method
|
199
|
+
method.call(*args, &block)
|
200
|
+
else
|
201
|
+
if method.respond_to?(kind)
|
202
|
+
method.send(kind, *args, &block)
|
203
|
+
else
|
204
|
+
raise ArgumentError,
|
205
|
+
"Callbacks must be a symbol denoting the method to call, a string to be evaluated, " +
|
206
|
+
"a block to be invoked, or an object responding to the callback method."
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def should_run_callback?(*args)
|
212
|
+
[options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
|
213
|
+
![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
|
214
|
+
end
|
215
|
+
end
|
63
216
|
end
|
64
217
|
end
|
65
218
|
end
|
@@ -175,6 +175,9 @@ module MongoMapper
|
|
175
175
|
writer_method = "#{name}="
|
176
176
|
|
177
177
|
if respond_to?(writer_method)
|
178
|
+
if writer_method == '_root_document='
|
179
|
+
puts "_root_document= #{value.inspect}"
|
180
|
+
end
|
178
181
|
self.send(writer_method, value)
|
179
182
|
else
|
180
183
|
self[name.to_s] = value
|
@@ -309,7 +312,11 @@ module MongoMapper
|
|
309
312
|
|
310
313
|
def get(value)
|
311
314
|
if value.nil? && !default_value.nil?
|
312
|
-
|
315
|
+
if default_value.respond_to?(:call)
|
316
|
+
return default_value.call
|
317
|
+
else
|
318
|
+
return default_value
|
319
|
+
end
|
313
320
|
end
|
314
321
|
|
315
322
|
type.from_mongo(value)
|
@@ -2,8 +2,8 @@ module MongoMapper
|
|
2
2
|
module Plugins
|
3
3
|
module Pagination
|
4
4
|
class Proxy
|
5
|
-
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
6
|
-
|
5
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|respond_to\?|proxy_|^object_id$)/ }
|
6
|
+
|
7
7
|
attr_accessor :subject
|
8
8
|
attr_reader :total_entries, :per_page, :current_page
|
9
9
|
alias limit per_page
|
@@ -50,7 +50,11 @@ module MongoMapper
|
|
50
50
|
def method_missing(name, *args, &block)
|
51
51
|
@subject.send(name, *args, &block)
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
|
+
def respond_to?(name, *args, &block)
|
55
|
+
super || @subject.respond_to?(name, *args, &block)
|
56
|
+
end
|
57
|
+
|
54
58
|
private
|
55
59
|
def per_page=(value)
|
56
60
|
value = 25 if value.blank?
|
data/lib/mongo_mapper/query.rb
CHANGED
data/lib/mongo_mapper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'set'
|
2
|
+
require 'uri'
|
2
3
|
|
3
4
|
# if Gem is defined i'll assume you are using rubygems and lock specific versions
|
4
5
|
# call me crazy but a plain old require will just get the latest version you have installed
|
@@ -10,7 +11,7 @@ if self.class.const_defined?(:Gem)
|
|
10
11
|
gem 'jnunemaker-validatable', '1.8.1'
|
11
12
|
end
|
12
13
|
|
13
|
-
require 'active_support'
|
14
|
+
require 'active_support/all'
|
14
15
|
require 'mongo'
|
15
16
|
require 'validatable'
|
16
17
|
|
@@ -24,6 +25,9 @@ module MongoMapper
|
|
24
25
|
# raised when document expected but not found
|
25
26
|
class DocumentNotFound < MongoMapperError; end
|
26
27
|
|
28
|
+
# raised when trying to connect using uri with incorrect scheme
|
29
|
+
class InvalidScheme < MongoMapperError; end
|
30
|
+
|
27
31
|
# raised when document not valid and using !
|
28
32
|
class DocumentNotValid < MongoMapperError
|
29
33
|
def initialize(document)
|
@@ -70,13 +74,28 @@ module MongoMapper
|
|
70
74
|
@@config
|
71
75
|
end
|
72
76
|
|
77
|
+
# @api private
|
78
|
+
def self.config_for_environment(environment)
|
79
|
+
env = config[environment]
|
80
|
+
return env if env['uri'].blank?
|
81
|
+
|
82
|
+
uri = URI.parse(env['uri'])
|
83
|
+
raise InvalidScheme.new('must be mongodb') unless uri.scheme == 'mongodb'
|
84
|
+
{
|
85
|
+
'host' => uri.host,
|
86
|
+
'port' => uri.port,
|
87
|
+
'database' => uri.path.gsub(/^\//, ''),
|
88
|
+
'username' => uri.user,
|
89
|
+
'password' => uri.password,
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
73
93
|
def self.connect(environment, options={})
|
74
94
|
raise 'Set config before connecting. MongoMapper.config = {...}' if config.blank?
|
75
|
-
|
76
|
-
MongoMapper.
|
77
|
-
|
78
|
-
|
79
|
-
end
|
95
|
+
env = config_for_environment(environment)
|
96
|
+
MongoMapper.connection = Mongo::Connection.new(env['host'], env['port'], options)
|
97
|
+
MongoMapper.database = env['database']
|
98
|
+
MongoMapper.database.authenticate(env['username'], env['password']) if env['username'] && env['password']
|
80
99
|
end
|
81
100
|
|
82
101
|
def self.setup(config, environment, options={})
|
@@ -108,11 +127,11 @@ module MongoMapper
|
|
108
127
|
def self.normalize_object_id(value)
|
109
128
|
value.is_a?(String) ? Mongo::ObjectID.from_string(value) : value
|
110
129
|
end
|
111
|
-
|
130
|
+
|
112
131
|
autoload :Query, 'mongo_mapper/query'
|
113
132
|
autoload :Document, 'mongo_mapper/document'
|
114
133
|
autoload :EmbeddedDocument, 'mongo_mapper/embedded_document'
|
115
134
|
end
|
116
135
|
|
117
136
|
require 'mongo_mapper/support'
|
118
|
-
require 'mongo_mapper/plugins'
|
137
|
+
require 'mongo_mapper/plugins'
|
@@ -12,7 +12,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
12
12
|
key :date, Date
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
context "array key" do
|
17
17
|
setup do
|
18
18
|
@document.key :tags, Array
|
@@ -115,6 +115,23 @@ class DocumentTest < Test::Unit::TestCase
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
context "key with proc default value" do
|
119
|
+
setup do
|
120
|
+
@document.key :proc_default, String, :default => lambda { return 'string' }
|
121
|
+
end
|
122
|
+
|
123
|
+
should "detect and run proc default" do
|
124
|
+
doc = @document.new
|
125
|
+
doc.proc_default.should == 'string'
|
126
|
+
end
|
127
|
+
|
128
|
+
should "save and load from mongo" do
|
129
|
+
doc = @document.create
|
130
|
+
doc = doc.reload
|
131
|
+
doc.proc_default.should == 'string'
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
118
135
|
context "ClassMethods#create (single document)" do
|
119
136
|
setup do
|
120
137
|
@doc_instance = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
@@ -139,7 +156,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
139
156
|
@doc_instance.last_name.should == 'Nunemaker'
|
140
157
|
@doc_instance.age.should == 27
|
141
158
|
end
|
142
|
-
|
159
|
+
|
143
160
|
should "not fail if no attributes provided" do
|
144
161
|
document = Doc()
|
145
162
|
lambda { document.create }.should change { document.count }.by(1)
|
@@ -183,12 +200,12 @@ class DocumentTest < Test::Unit::TestCase
|
|
183
200
|
should "not create new document" do
|
184
201
|
@document.count.should == 1
|
185
202
|
end
|
186
|
-
|
203
|
+
|
187
204
|
should "raise error if not provided id" do
|
188
205
|
doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
189
206
|
lambda { @document.update }.should raise_error(ArgumentError)
|
190
207
|
end
|
191
|
-
|
208
|
+
|
192
209
|
should "raise error if not provided attributes" do
|
193
210
|
doc = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
|
194
211
|
lambda { @document.update(doc._id) }.should raise_error(ArgumentError)
|
@@ -221,7 +238,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
221
238
|
@document.find(@doc1._id).age.should == 30
|
222
239
|
@document.find(@doc2._id).age.should == 30
|
223
240
|
end
|
224
|
-
|
241
|
+
|
225
242
|
should "raise error if not a hash" do
|
226
243
|
lambda { @document.update([1, 2]) }.should raise_error(ArgumentError)
|
227
244
|
end
|
@@ -243,7 +260,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
243
260
|
@document.find!
|
244
261
|
end
|
245
262
|
end
|
246
|
-
|
263
|
+
|
247
264
|
should "raise error if trying to find with :all, :first, or :last" do
|
248
265
|
[:all, :first, :last].each do |m|
|
249
266
|
assert_raises(ArgumentError) { @document.find(m) }
|
@@ -525,7 +542,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
525
542
|
@doc2 = @document.create({:first_name => 'Steve', :last_name => 'Smith', :age => '28'})
|
526
543
|
@doc3 = @document.create({:first_name => 'Steph', :last_name => 'Nunemaker', :age => '26'})
|
527
544
|
@document.destroy(@doc1._id, @doc2._id)
|
528
|
-
|
545
|
+
|
529
546
|
@document.count.should == 1
|
530
547
|
end
|
531
548
|
|
@@ -596,11 +613,11 @@ class DocumentTest < Test::Unit::TestCase
|
|
596
613
|
@document.count(:age => [26, 27]).should == 2
|
597
614
|
end
|
598
615
|
end
|
599
|
-
|
616
|
+
|
600
617
|
should "have instance method for collection" do
|
601
618
|
@document.new.collection.name.should == @document.collection.name
|
602
619
|
end
|
603
|
-
|
620
|
+
|
604
621
|
should "have instance method for database" do
|
605
622
|
@document.new.database.should == @document.database
|
606
623
|
end
|
@@ -672,7 +689,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
672
689
|
@document.new.update_attributes({}).should be_false
|
673
690
|
end
|
674
691
|
end
|
675
|
-
|
692
|
+
|
676
693
|
context "#save (new document)" do
|
677
694
|
setup do
|
678
695
|
@doc = @document.new(:first_name => 'John', :age => '27')
|
@@ -710,12 +727,12 @@ class DocumentTest < Test::Unit::TestCase
|
|
710
727
|
should "allow to use custom methods to assign properties" do
|
711
728
|
klass = Doc do
|
712
729
|
key :name, String
|
713
|
-
|
730
|
+
|
714
731
|
def realname=(value)
|
715
732
|
self.name = value
|
716
733
|
end
|
717
734
|
end
|
718
|
-
|
735
|
+
|
719
736
|
person = klass.new(:realname => 'David')
|
720
737
|
person.save
|
721
738
|
person.reload.name.should == 'David'
|
@@ -723,7 +740,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
723
740
|
|
724
741
|
context "with key of type date" do
|
725
742
|
should "save the date value as a Time object" do
|
726
|
-
doc = @document.new(:first_name => 'John', :age => '27', :date => "12
|
743
|
+
doc = @document.new(:first_name => 'John', :age => '27', :date => "2009-12-01")
|
727
744
|
doc.save
|
728
745
|
doc.date.should == Date.new(2009, 12, 1)
|
729
746
|
end
|
@@ -775,7 +792,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
775
792
|
@document.count.should == 1
|
776
793
|
end
|
777
794
|
end
|
778
|
-
|
795
|
+
|
779
796
|
context "#save (with options)" do
|
780
797
|
setup do
|
781
798
|
@document = Doc do
|
@@ -799,7 +816,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
799
816
|
end
|
800
817
|
end
|
801
818
|
end
|
802
|
-
|
819
|
+
|
803
820
|
context "#save! (with options)" do
|
804
821
|
setup do
|
805
822
|
@document = Doc do
|
@@ -840,37 +857,57 @@ class DocumentTest < Test::Unit::TestCase
|
|
840
857
|
@document.count.should == 0
|
841
858
|
end
|
842
859
|
end
|
843
|
-
|
860
|
+
|
844
861
|
context "#delete" do
|
845
862
|
setup do
|
846
|
-
@doc1 = @document.create(
|
847
|
-
@doc2 = @document.create(
|
848
|
-
|
863
|
+
@doc1 = @document.create(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
|
864
|
+
@doc2 = @document.create(:first_name => 'Steve', :last_name => 'Smith', :age => '28')
|
865
|
+
|
849
866
|
@document.class_eval do
|
850
867
|
before_destroy :before_destroy_callback
|
851
868
|
after_destroy :after_destroy_callback
|
852
|
-
|
869
|
+
|
853
870
|
def history; @history ||= [] end
|
854
871
|
def before_destroy_callback; history << :after_destroy end
|
855
872
|
def after_destroy_callback; history << :after_destroy end
|
856
873
|
end
|
857
|
-
|
874
|
+
|
858
875
|
@doc1.delete
|
859
876
|
end
|
860
877
|
|
861
878
|
should "remove document from collection" do
|
862
879
|
@document.count.should == 1
|
863
880
|
end
|
864
|
-
|
881
|
+
|
865
882
|
should "not remove other documents" do
|
866
883
|
@document.find(@doc2.id).should_not be(nil)
|
867
884
|
end
|
868
|
-
|
885
|
+
|
869
886
|
should "not call before/after destroy callbacks" do
|
870
887
|
@doc1.history.should == []
|
871
888
|
end
|
872
889
|
end
|
873
890
|
|
891
|
+
context "#destroyed?" do
|
892
|
+
setup do
|
893
|
+
@doc1 = @document.create(:first_name => 'John', :last_name => 'Nunemaker', :age => '27')
|
894
|
+
end
|
895
|
+
|
896
|
+
should "be true if deleted" do
|
897
|
+
@doc1.delete
|
898
|
+
assert @doc1.destroyed?
|
899
|
+
end
|
900
|
+
|
901
|
+
should "be true if destroyed" do
|
902
|
+
@doc1.destroy
|
903
|
+
assert @doc1.destroyed?
|
904
|
+
end
|
905
|
+
|
906
|
+
should "be false if not deleted or destroyed" do
|
907
|
+
assert ! @doc1.destroyed?
|
908
|
+
end
|
909
|
+
end
|
910
|
+
|
874
911
|
context "Single collection inheritance" do
|
875
912
|
setup do
|
876
913
|
class ::DocParent
|
@@ -883,7 +920,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
883
920
|
class ::DocDaughter < ::DocParent; end
|
884
921
|
class ::DocSon < ::DocParent; end
|
885
922
|
class ::DocGrandSon < ::DocSon; end
|
886
|
-
|
923
|
+
|
887
924
|
DocSon.many :children, :class_name => 'DocGrandSon'
|
888
925
|
|
889
926
|
@parent = DocParent.new({:name => "Daddy Warbucks"})
|
@@ -939,7 +976,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
939
976
|
DocDaughter.all(:order => 'name').should == [carrie, steph]
|
940
977
|
DocParent.all(:order => 'name').should == [carrie, john, steph, steve]
|
941
978
|
end
|
942
|
-
|
979
|
+
|
943
980
|
should "work with nested hash conditions" do
|
944
981
|
john = DocSon.create(:name => 'John')
|
945
982
|
steve = DocSon.create(:name => 'Steve')
|
@@ -1023,7 +1060,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
1023
1060
|
DocParent.delete_all
|
1024
1061
|
}.should change { DocParent.count }.by(-2)
|
1025
1062
|
end
|
1026
|
-
|
1063
|
+
|
1027
1064
|
should "be able to reload parent inherited class" do
|
1028
1065
|
brian = DocParent.create(:name => 'Brian')
|
1029
1066
|
brian.name = 'B-Dawg'
|
@@ -1053,7 +1090,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
1053
1090
|
doc.created_at.should_not be(nil)
|
1054
1091
|
doc.updated_at.should_not be(nil)
|
1055
1092
|
end
|
1056
|
-
|
1093
|
+
|
1057
1094
|
should "not overwrite created_at if it already exists" do
|
1058
1095
|
original_created_at = 1.month.ago
|
1059
1096
|
doc = @klass.new(:first_name => 'John', :age => 27, :created_at => original_created_at)
|
@@ -1097,19 +1134,19 @@ class DocumentTest < Test::Unit::TestCase
|
|
1097
1134
|
setup do
|
1098
1135
|
@document.userstamps!
|
1099
1136
|
end
|
1100
|
-
|
1137
|
+
|
1101
1138
|
should "add creator_id key" do
|
1102
1139
|
@document.keys.keys.should include('creator_id')
|
1103
1140
|
end
|
1104
|
-
|
1141
|
+
|
1105
1142
|
should "add updater_id key" do
|
1106
1143
|
@document.keys.keys.should include('updater_id')
|
1107
1144
|
end
|
1108
|
-
|
1145
|
+
|
1109
1146
|
should "add belongs_to creator" do
|
1110
1147
|
@document.associations.keys.should include('creator')
|
1111
1148
|
end
|
1112
|
-
|
1149
|
+
|
1113
1150
|
should "add belongs_to updater" do
|
1114
1151
|
@document.associations.keys.should include('updater')
|
1115
1152
|
end
|
@@ -1143,14 +1180,14 @@ class DocumentTest < Test::Unit::TestCase
|
|
1143
1180
|
@foo_class = Doc do
|
1144
1181
|
key :name
|
1145
1182
|
end
|
1146
|
-
|
1183
|
+
|
1147
1184
|
@bar_class = EDoc do
|
1148
1185
|
key :name
|
1149
1186
|
end
|
1150
|
-
|
1187
|
+
|
1151
1188
|
@document.many :foos, :class => @foo_class
|
1152
1189
|
@document.many :bars, :class => @bar_class
|
1153
|
-
|
1190
|
+
|
1154
1191
|
@instance = @document.create({
|
1155
1192
|
:age => 39,
|
1156
1193
|
:foos => [@foo_class.new(:name => '1')],
|
@@ -1164,22 +1201,22 @@ class DocumentTest < Test::Unit::TestCase
|
|
1164
1201
|
@instance.reload
|
1165
1202
|
@instance.age.should == 39
|
1166
1203
|
end
|
1167
|
-
|
1204
|
+
|
1168
1205
|
should "reset all associations" do
|
1169
1206
|
@instance.foos.expects(:reset).at_least_once
|
1170
1207
|
@instance.bars.expects(:reset).at_least_once
|
1171
1208
|
@instance.reload
|
1172
1209
|
end
|
1173
|
-
|
1210
|
+
|
1174
1211
|
should "reinstantiate embedded associations" do
|
1175
1212
|
@instance.reload
|
1176
1213
|
@instance.bars.first.name.should == '1'
|
1177
1214
|
end
|
1178
|
-
|
1215
|
+
|
1179
1216
|
should "return self" do
|
1180
1217
|
@instance.reload.object_id.should == @instance.object_id
|
1181
1218
|
end
|
1182
|
-
|
1219
|
+
|
1183
1220
|
should "raise DocumentNotFound if not found" do
|
1184
1221
|
@instance.destroy
|
1185
1222
|
assert_raises(MongoMapper::DocumentNotFound) { @instance.reload }
|
@@ -1226,7 +1263,7 @@ class DocumentTest < Test::Unit::TestCase
|
|
1226
1263
|
|
1227
1264
|
should "allow creating index on multiple keys" do
|
1228
1265
|
@document.ensure_index [[:first_name, 1], [:last_name, -1]]
|
1229
|
-
|
1266
|
+
|
1230
1267
|
# order is different for different versions of ruby so instead of
|
1231
1268
|
# just checking have_index('first_name_1_last_name_-1') I'm checking
|
1232
1269
|
# the values of the indexes to make sure the index creation was successful
|
@@ -7,27 +7,27 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
|
|
7
7
|
key :first_name, String
|
8
8
|
key :last_name, String
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
@pet_klass = EDoc do
|
12
12
|
key :name, String
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
@klass.many :pets, :class => @pet_klass
|
16
|
-
|
16
|
+
|
17
17
|
@address_class = EDoc do
|
18
18
|
key :city, String
|
19
19
|
key :state, String
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
23
|
-
context "Saving a document with an embedded document" do
|
22
|
+
|
23
|
+
context "Saving a document with a key that is an embedded document" do
|
24
24
|
setup do
|
25
25
|
@klass.key :foo, @address_class
|
26
|
-
|
26
|
+
|
27
27
|
@address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
28
28
|
@doc = @klass.new(:foo => @address)
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
should "embed embedded document" do
|
32
32
|
@doc.save
|
33
33
|
@doc.foo.city.should == 'South Bend'
|
@@ -38,16 +38,16 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
|
|
38
38
|
doc.foo.state.should == 'IN'
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
should "correctly instantiate single collection inherited embedded documents" do
|
43
43
|
document = Doc('Foo') do
|
44
44
|
key :message, Message
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
doc1 = document.create(:message => Enter.new)
|
48
48
|
doc1.reload.message.class.should be(Enter)
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
context "new?" do
|
52
52
|
setup do
|
53
53
|
@klass.key :foo, @address_class
|
@@ -58,65 +58,65 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
|
|
58
58
|
doc = @klass.new(:foo => address)
|
59
59
|
address.new?.should == true
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
should "not be new after document is saved" do
|
63
63
|
address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
64
64
|
doc = @klass.new(:foo => address)
|
65
65
|
doc.save
|
66
66
|
doc.foo.new?.should == false
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
should "not be new when document is read back" do
|
70
70
|
address = @address_class.new(:city => 'South Bend', :state => 'IN')
|
71
71
|
doc = @klass.new(:foo => address)
|
72
72
|
doc.save
|
73
|
-
|
73
|
+
|
74
74
|
doc = doc.reload
|
75
75
|
doc.foo.new?.should == false
|
76
76
|
end
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
should "be able to save" do
|
80
80
|
person = @klass.create
|
81
|
-
|
81
|
+
|
82
82
|
pet = @pet_klass.new(:name => 'sparky')
|
83
83
|
person.pets << pet
|
84
84
|
pet.should be_new
|
85
85
|
pet.save
|
86
86
|
pet.should_not be_new
|
87
|
-
|
87
|
+
|
88
88
|
person.reload
|
89
89
|
person.pets.first.should == pet
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
should "be able to dynamically add new keys and save" do
|
93
93
|
person = @klass.create
|
94
|
-
|
94
|
+
|
95
95
|
pet = @pet_klass.new(:name => 'sparky', :crazy_key => 'crazy')
|
96
96
|
person.pets << pet
|
97
97
|
pet.save
|
98
|
-
|
98
|
+
|
99
99
|
person.reload
|
100
100
|
person.pets.first.crazy_key.should == 'crazy'
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
should "be able to update_attributes" do
|
104
104
|
pet = @pet_klass.new(:name => 'sparky')
|
105
105
|
person = @klass.create(:pets => [pet])
|
106
106
|
person.reload
|
107
107
|
pet = person.pets.first
|
108
|
-
|
108
|
+
|
109
109
|
pet.update_attributes(:name => 'koda').should be_true
|
110
110
|
person.reload
|
111
111
|
person.pets.first._id.should == pet._id
|
112
112
|
person.pets.first.name.should == 'koda'
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
should "be able to update_attributes!" do
|
116
116
|
person = @klass.create(:pets => [@pet_klass.new(:name => 'sparky')])
|
117
117
|
person.reload
|
118
118
|
pet = person.pets.first
|
119
|
-
|
119
|
+
|
120
120
|
attributes = {:name => 'koda'}
|
121
121
|
pet.expects(:attributes=).with(attributes)
|
122
122
|
pet.expects(:save!)
|
data/test/support/timing.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -42,7 +42,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
|
|
42
42
|
Object.send :remove_const, 'Child' if defined?(::Child)
|
43
43
|
Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
context "Including MongoMapper::EmbeddedDocument in a class" do
|
47
47
|
setup do
|
48
48
|
@klass = EDoc()
|
@@ -249,34 +249,34 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
|
|
249
249
|
|
250
250
|
should "convert string object id to mongo object id when assigning id with _id object id type" do
|
251
251
|
id = Mongo::ObjectID.new
|
252
|
-
|
253
252
|
doc = @document.new(:id => id.to_s)
|
254
253
|
doc._id.should == id
|
255
|
-
doc.id.should
|
256
|
-
|
254
|
+
doc.id.should == id
|
257
255
|
doc = @document.new(:_id => id.to_s)
|
258
256
|
doc._id.should == id
|
259
|
-
doc.id.should
|
257
|
+
doc.id.should == id
|
260
258
|
end
|
261
259
|
|
262
|
-
context "
|
260
|
+
context "_parent_document" do
|
263
261
|
should "default to nil" do
|
262
|
+
@document.new._parent_document.should be_nil
|
264
263
|
@document.new._root_document.should be_nil
|
265
264
|
end
|
266
265
|
|
267
|
-
should "
|
266
|
+
should "set _root_document when setting _parent_document" do
|
268
267
|
root = Doc().new
|
269
|
-
doc = @document.new
|
270
|
-
|
268
|
+
doc = @document.new(:_parent_document => root)
|
269
|
+
doc._parent_document.should be(root)
|
271
270
|
doc._root_document.should be(root)
|
272
271
|
end
|
273
272
|
|
274
|
-
should "
|
275
|
-
root
|
276
|
-
klass
|
277
|
-
|
278
|
-
|
279
|
-
|
273
|
+
should "set _root_document when setting _parent_document on embedded many" do
|
274
|
+
root = Doc().new
|
275
|
+
klass = EDoc { many :children }
|
276
|
+
parent = klass.new(:_parent_document => root, :children => [{}])
|
277
|
+
child = parent.children.first
|
278
|
+
child._parent_document.should be(parent)
|
279
|
+
child._root_document.should be(root)
|
280
280
|
end
|
281
281
|
end
|
282
282
|
|
data/test/unit/test_keys.rb
CHANGED
@@ -42,25 +42,25 @@ class KeyTest < Test::Unit::TestCase
|
|
42
42
|
should "symbolize option keys" do
|
43
43
|
Key.new(:foo, Integer, 'required' => true).options[:required].should be(true)
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
should "work with just name" do
|
47
47
|
key = Key.new(:foo)
|
48
48
|
key.name.should == 'foo'
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
should "work with name and type" do
|
52
52
|
key = Key.new(:foo, String)
|
53
53
|
key.name.should == 'foo'
|
54
54
|
key.type.should == String
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
should "work with name, type, and options" do
|
58
58
|
key = Key.new(:foo, String, :required => true)
|
59
59
|
key.name.should == 'foo'
|
60
60
|
key.type.should == String
|
61
61
|
key.options[:required].should be_true
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
should "work with name and options" do
|
65
65
|
key = Key.new(:foo, :required => true)
|
66
66
|
key.name.should == 'foo'
|
@@ -80,7 +80,7 @@ class KeyTest < Test::Unit::TestCase
|
|
80
80
|
should "not be equal to another key with different type" do
|
81
81
|
Key.new(:name, String).should_not == Key.new(:name, Integer)
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
should "know if it is a embedded_document" do
|
85
85
|
Key.new(:name, EDoc()).embeddable?.should be_true
|
86
86
|
end
|
@@ -88,12 +88,12 @@ class KeyTest < Test::Unit::TestCase
|
|
88
88
|
should "know if it is not a embedded_document" do
|
89
89
|
Key.new(:name, String).embeddable?.should be_false
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
should "know if it is a number" do
|
93
93
|
Key.new(:age, Integer).number?.should be_true
|
94
94
|
Key.new(:age, Float).number?.should be_true
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
should "know if it is not a number" do
|
98
98
|
Key.new(:age, String).number?.should be_false
|
99
99
|
end
|
@@ -110,7 +110,7 @@ class KeyTest < Test::Unit::TestCase
|
|
110
110
|
key.set(FooType.new('something')).should == 'to_mongo'
|
111
111
|
end
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
context "getting a value with a custom type" do
|
115
115
|
should "use #from_mongo to convert back to custom type" do
|
116
116
|
key = Key.new(:foo, FooType)
|
@@ -123,7 +123,7 @@ class KeyTest < Test::Unit::TestCase
|
|
123
123
|
key = Key.new(:foo, String)
|
124
124
|
key.get('bar').should == 'bar'
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
should "work without type" do
|
128
128
|
key = Key.new(:foo)
|
129
129
|
key.get([1, '2']).should == [1, '2']
|
@@ -144,7 +144,7 @@ class KeyTest < Test::Unit::TestCase
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
context "getting a value with a default set" do
|
149
149
|
setup do
|
150
150
|
@key = Key.new(:foo, String, :default => 'baz')
|
@@ -157,7 +157,7 @@ class KeyTest < Test::Unit::TestCase
|
|
157
157
|
should "return value if not blank" do
|
158
158
|
@key.get('foobar').should == 'foobar'
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
should "work with Boolean type and false value" do
|
162
162
|
Key.new(:active, Boolean, :default => false).get(nil).should be_false
|
163
163
|
end
|
@@ -165,5 +165,9 @@ class KeyTest < Test::Unit::TestCase
|
|
165
165
|
should "work with Boolean type and true value" do
|
166
166
|
Key.new(:active, Boolean, :default => true).get(nil).should be_true
|
167
167
|
end
|
168
|
+
|
169
|
+
should "work with procs" do
|
170
|
+
Key.new(:foo, String, :default => lambda { return 'hello world' }).get(nil).should == "hello world"
|
171
|
+
end
|
168
172
|
end
|
169
173
|
end # KeyTest
|
@@ -31,7 +31,6 @@ class MongoMapperTest < Test::Unit::TestCase
|
|
31
31
|
'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test'},
|
32
32
|
'production' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test-prod'}
|
33
33
|
}
|
34
|
-
|
35
34
|
MongoMapper.config = config
|
36
35
|
MongoMapper.config.should == config
|
37
36
|
end
|
@@ -41,7 +40,16 @@ class MongoMapperTest < Test::Unit::TestCase
|
|
41
40
|
MongoMapper.config = {
|
42
41
|
'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test'}
|
43
42
|
}
|
43
|
+
Mongo::Connection.expects(:new).with('127.0.0.1', 27017, {})
|
44
|
+
MongoMapper.expects(:database=).with('test')
|
45
|
+
Mongo::DB.any_instance.expects(:authenticate).never
|
46
|
+
MongoMapper.connect('development')
|
47
|
+
end
|
44
48
|
|
49
|
+
should "work without authentication using uri" do
|
50
|
+
MongoMapper.config = {
|
51
|
+
'development' => {'uri' => 'mongodb://127.0.0.1:27017/test'}
|
52
|
+
}
|
45
53
|
Mongo::Connection.expects(:new).with('127.0.0.1', 27017, {})
|
46
54
|
MongoMapper.expects(:database=).with('test')
|
47
55
|
Mongo::DB.any_instance.expects(:authenticate).never
|
@@ -52,7 +60,15 @@ class MongoMapperTest < Test::Unit::TestCase
|
|
52
60
|
MongoMapper.config = {
|
53
61
|
'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test'}
|
54
62
|
}
|
63
|
+
connection, logger = mock('connection'), mock('logger')
|
64
|
+
Mongo::Connection.expects(:new).with('127.0.0.1', 27017, :logger => logger)
|
65
|
+
MongoMapper.connect('development', :logger => logger)
|
66
|
+
end
|
55
67
|
|
68
|
+
should "work with options using uri" do
|
69
|
+
MongoMapper.config = {
|
70
|
+
'development' => {'uri' => 'mongodb://127.0.0.1:27017/test'}
|
71
|
+
}
|
56
72
|
connection, logger = mock('connection'), mock('logger')
|
57
73
|
Mongo::Connection.expects(:new).with('127.0.0.1', 27017, :logger => logger)
|
58
74
|
MongoMapper.connect('development', :logger => logger)
|
@@ -62,10 +78,24 @@ class MongoMapperTest < Test::Unit::TestCase
|
|
62
78
|
MongoMapper.config = {
|
63
79
|
'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test', 'username' => 'john', 'password' => 'secret'}
|
64
80
|
}
|
81
|
+
Mongo::DB.any_instance.expects(:authenticate).with('john', 'secret')
|
82
|
+
MongoMapper.connect('development')
|
83
|
+
end
|
65
84
|
|
85
|
+
should "work with authentication using uri" do
|
86
|
+
MongoMapper.config = {
|
87
|
+
'development' => {'uri' => 'mongodb://john:secret@127.0.0.1:27017/test'}
|
88
|
+
}
|
66
89
|
Mongo::DB.any_instance.expects(:authenticate).with('john', 'secret')
|
67
90
|
MongoMapper.connect('development')
|
68
91
|
end
|
92
|
+
|
93
|
+
should "raise error for invalid scheme" do
|
94
|
+
MongoMapper.config = {
|
95
|
+
'development' => {'uri' => 'mysql://127.0.0.1:5336/foo'}
|
96
|
+
}
|
97
|
+
assert_raises(MongoMapper::InvalidScheme) { MongoMapper.connect('development') }
|
98
|
+
end
|
69
99
|
end
|
70
100
|
|
71
101
|
context "setup" do
|
@@ -12,6 +12,29 @@ class PaginationTest < Test::Unit::TestCase
|
|
12
12
|
context "Pagination proxy" do
|
13
13
|
include MongoMapper::Plugins::Pagination
|
14
14
|
|
15
|
+
should "respond_to? correctly on proxy readers" do
|
16
|
+
proxy = Proxy.new(25, 10, 4)
|
17
|
+
proxy.respond_to?(:subject).should be_true
|
18
|
+
proxy.respond_to?(:total_entries).should be_true
|
19
|
+
proxy.respond_to?(:per_page).should be_true
|
20
|
+
proxy.respond_to?(:current_page).should be_true
|
21
|
+
proxy.respond_to?(:limit).should be_true
|
22
|
+
proxy.respond_to?(:total_pages).should be_true
|
23
|
+
proxy.respond_to?(:out_of_bounds?).should be_true
|
24
|
+
proxy.respond_to?(:previous_page).should be_true
|
25
|
+
proxy.respond_to?(:next_page).should be_true
|
26
|
+
proxy.respond_to?(:skip).should be_true
|
27
|
+
proxy.respond_to?(:offset).should be_true
|
28
|
+
|
29
|
+
# make sure it doesnt respond true to everything
|
30
|
+
proxy.respond_to?(:blahblahblah).should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
should "respond_to? correctly on proxy writers" do
|
34
|
+
proxy = Proxy.new(25, 10, 4)
|
35
|
+
proxy.respond_to?(:subject=).should be_true
|
36
|
+
end
|
37
|
+
|
15
38
|
should "should have accessors for subject" do
|
16
39
|
subject = [1,2,3,4,5]
|
17
40
|
collection = Proxy.new(25, 2)
|
@@ -31,6 +54,16 @@ class PaginationTest < Test::Unit::TestCase
|
|
31
54
|
collection.class.should == Array
|
32
55
|
end
|
33
56
|
|
57
|
+
should "should respond_to? correctly for methods defined on the subject" do
|
58
|
+
subject = [1,2,3,4,5]
|
59
|
+
def subject.blahblah
|
60
|
+
"BLAHBLAH"
|
61
|
+
end
|
62
|
+
collection = Proxy.new(25, 2, 10)
|
63
|
+
collection.subject = subject
|
64
|
+
collection.respond_to?(:blahblah).should be_true
|
65
|
+
end
|
66
|
+
|
34
67
|
should "return correct value for total_entries" do
|
35
68
|
Proxy.new(25, 2, 10).total_entries.should == 25
|
36
69
|
Proxy.new('25', 2, 10).total_entries.should == 25
|
data/test/unit/test_query.rb
CHANGED
@@ -38,6 +38,8 @@ class QueryTest < Test::Unit::TestCase
|
|
38
38
|
end
|
39
39
|
|
40
40
|
%w{gt lt gte lte ne in nin mod all size where exists}.each do |operator|
|
41
|
+
next if operator == 'size' && RUBY_VERSION >= '1.9.1' # 1.9 defines Symbol#size
|
42
|
+
|
41
43
|
should "convert #{operator} conditions" do
|
42
44
|
Query.new(Room, :age.send(operator) => 21).criteria.should == {
|
43
45
|
:age => {"$#{operator}" => 21}
|
@@ -176,6 +178,10 @@ class QueryTest < Test::Unit::TestCase
|
|
176
178
|
Query.new(Room, :sort => sort, :order => 'foo asc').options[:sort].should == sort
|
177
179
|
end
|
178
180
|
|
181
|
+
should "normalize id to _id" do
|
182
|
+
Query.new(Room, :order => :id.asc).options[:sort].should == [['_id', 1]]
|
183
|
+
end
|
184
|
+
|
179
185
|
should "convert natural in order to proper" do
|
180
186
|
sort = [['$natural', 1]]
|
181
187
|
Query.new(Room, :order => '$natural asc').options[:sort].should == sort
|
data/test/unit/test_support.rb
CHANGED
@@ -78,7 +78,7 @@ class SupportTest < Test::Unit::TestCase
|
|
78
78
|
|
79
79
|
context "Date#to_mongo" do
|
80
80
|
should "be time if string" do
|
81
|
-
date = Date.to_mongo('10
|
81
|
+
date = Date.to_mongo('2009-10-01')
|
82
82
|
date.should == Time.utc(2009, 10, 1)
|
83
83
|
date.should == date
|
84
84
|
date.month.should == 10
|
@@ -276,8 +276,12 @@ class SupportTest < Test::Unit::TestCase
|
|
276
276
|
end
|
277
277
|
|
278
278
|
context "Time#to_mongo without Time.zone" do
|
279
|
+
setup do
|
280
|
+
Time.zone = nil
|
281
|
+
end
|
282
|
+
|
279
283
|
should "be time to milliseconds if string" do
|
280
|
-
Time.to_mongo('2000-01-01 01:01:01.123456').should == Time.local(2000, 1, 1, 1, 1, 1, 123000).utc
|
284
|
+
Time.to_mongo('2000-01-01 01:01:01.123456').to_f.should == Time.local(2000, 1, 1, 1, 1, 1, 123000).utc.to_f
|
281
285
|
end
|
282
286
|
|
283
287
|
should "be time in utc if time" do
|
@@ -296,13 +300,13 @@ class SupportTest < Test::Unit::TestCase
|
|
296
300
|
context "Time#to_mongo with Time.zone" do
|
297
301
|
should "be time to milliseconds if time" do
|
298
302
|
Time.zone = 'Hawaii'
|
299
|
-
Time.to_mongo(Time.zone.local(2009, 8, 15, 14, 0, 0, 123456)).should == Time.utc(2009, 8, 16, 0, 0, 0, 123000)
|
303
|
+
Time.to_mongo(Time.zone.local(2009, 8, 15, 14, 0, 0, 123456)).to_f.should == Time.utc(2009, 8, 16, 0, 0, 0, 123000).to_f
|
300
304
|
Time.zone = nil
|
301
305
|
end
|
302
306
|
|
303
307
|
should "be time to milliseconds if string" do
|
304
308
|
Time.zone = 'Hawaii'
|
305
|
-
Time.to_mongo('2009-08-15 14:00:00.123456').should == Time.utc(2009, 8, 16, 0, 0, 0, 123000)
|
309
|
+
Time.to_mongo('2009-08-15 14:00:00.123456').to_f.should == Time.utc(2009, 8, 16, 0, 0, 0, 123000).to_f
|
306
310
|
Time.zone = nil
|
307
311
|
end
|
308
312
|
|
@@ -359,4 +363,4 @@ class SupportTest < Test::Unit::TestCase
|
|
359
363
|
id.original_to_json.should == %Q({"$oid": "#{id}"})
|
360
364
|
end
|
361
365
|
end
|
362
|
-
end
|
366
|
+
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.2.
|
4
|
+
version: 2010.2.28
|
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-02-
|
12
|
+
date: 2010-02-28 00:00:00 -05:00
|
13
13
|
default_executable: mmconsole
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|