mongo_doc 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/LICENSE +20 -0
- data/README.textile +174 -0
- data/Rakefile +135 -0
- data/TODO +31 -0
- data/VERSION +1 -0
- data/data/.gitignore +2 -0
- data/examples/simple_document.rb +35 -0
- data/examples/simple_object.rb +30 -0
- data/features/finders.feature +76 -0
- data/features/mongodb.yml +7 -0
- data/features/mongodoc_base.feature +128 -0
- data/features/new_record.feature +36 -0
- data/features/partial_updates.feature +105 -0
- data/features/removing_documents.feature +68 -0
- data/features/saving_an_object.feature +15 -0
- data/features/scopes.feature +66 -0
- data/features/step_definitions/collection_steps.rb +14 -0
- data/features/step_definitions/document_steps.rb +149 -0
- data/features/step_definitions/documents.rb +30 -0
- data/features/step_definitions/finder_steps.rb +15 -0
- data/features/step_definitions/json_steps.rb +9 -0
- data/features/step_definitions/object_steps.rb +50 -0
- data/features/step_definitions/objects.rb +24 -0
- data/features/step_definitions/partial_update_steps.rb +32 -0
- data/features/step_definitions/query_steps.rb +54 -0
- data/features/step_definitions/removing_documents_steps.rb +14 -0
- data/features/step_definitions/scope_steps.rb +18 -0
- data/features/step_definitions/util_steps.rb +7 -0
- data/features/support/support.rb +10 -0
- data/features/using_criteria.feature +128 -0
- data/lib/mongo_doc/associations/collection_proxy.rb +105 -0
- data/lib/mongo_doc/associations/document_proxy.rb +56 -0
- data/lib/mongo_doc/associations/hash_proxy.rb +98 -0
- data/lib/mongo_doc/associations/proxy_base.rb +53 -0
- data/lib/mongo_doc/attributes.rb +140 -0
- data/lib/mongo_doc/bson.rb +45 -0
- data/lib/mongo_doc/collection.rb +55 -0
- data/lib/mongo_doc/connection.rb +88 -0
- data/lib/mongo_doc/contexts/enumerable.rb +128 -0
- data/lib/mongo_doc/contexts/ids.rb +41 -0
- data/lib/mongo_doc/contexts/mongo.rb +232 -0
- data/lib/mongo_doc/contexts.rb +25 -0
- data/lib/mongo_doc/criteria.rb +38 -0
- data/lib/mongo_doc/cursor.rb +32 -0
- data/lib/mongo_doc/document.rb +216 -0
- data/lib/mongo_doc/ext/array.rb +5 -0
- data/lib/mongo_doc/ext/binary.rb +7 -0
- data/lib/mongo_doc/ext/boolean_class.rb +11 -0
- data/lib/mongo_doc/ext/date.rb +16 -0
- data/lib/mongo_doc/ext/date_time.rb +13 -0
- data/lib/mongo_doc/ext/dbref.rb +7 -0
- data/lib/mongo_doc/ext/hash.rb +7 -0
- data/lib/mongo_doc/ext/nil_class.rb +5 -0
- data/lib/mongo_doc/ext/numeric.rb +17 -0
- data/lib/mongo_doc/ext/object.rb +17 -0
- data/lib/mongo_doc/ext/object_id.rb +7 -0
- data/lib/mongo_doc/ext/regexp.rb +5 -0
- data/lib/mongo_doc/ext/string.rb +5 -0
- data/lib/mongo_doc/ext/symbol.rb +5 -0
- data/lib/mongo_doc/ext/time.rb +5 -0
- data/lib/mongo_doc/finders.rb +49 -0
- data/lib/mongo_doc/matchers.rb +35 -0
- data/lib/mongo_doc/query.rb +7 -0
- data/lib/mongo_doc/scope.rb +64 -0
- data/lib/mongo_doc/validations/macros.rb +11 -0
- data/lib/mongo_doc/validations/validates_embedded.rb +13 -0
- data/lib/mongo_doc.rb +19 -0
- data/lib/mongoid/contexts/paging.rb +42 -0
- data/lib/mongoid/criteria.rb +247 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +92 -0
- data/lib/mongoid/criterion/optional.rb +136 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +26 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/mongo_doc.gemspec +205 -0
- data/mongod.example.yml +2 -0
- data/mongodb.example.yml +14 -0
- data/perf/mongo_doc_runner.rb +90 -0
- data/perf/ruby_driver_runner.rb +64 -0
- data/script/console +8 -0
- data/spec/associations/collection_proxy_spec.rb +200 -0
- data/spec/associations/document_proxy_spec.rb +42 -0
- data/spec/associations/hash_proxy_spec.rb +163 -0
- data/spec/attributes_spec.rb +273 -0
- data/spec/bson_matchers.rb +54 -0
- data/spec/bson_spec.rb +196 -0
- data/spec/collection_spec.rb +161 -0
- data/spec/connection_spec.rb +147 -0
- data/spec/contexts/enumerable_spec.rb +274 -0
- data/spec/contexts/ids_spec.rb +49 -0
- data/spec/contexts/mongo_spec.rb +198 -0
- data/spec/contexts_spec.rb +28 -0
- data/spec/criteria_spec.rb +33 -0
- data/spec/cursor_spec.rb +91 -0
- data/spec/document_ext.rb +9 -0
- data/spec/document_spec.rb +664 -0
- data/spec/embedded_save_spec.rb +109 -0
- data/spec/finders_spec.rb +73 -0
- data/spec/hash_matchers.rb +27 -0
- data/spec/matchers_spec.rb +342 -0
- data/spec/mongodb.yml +6 -0
- data/spec/mongodb_pairs.yml +8 -0
- data/spec/new_record_spec.rb +128 -0
- data/spec/query_spec.rb +12 -0
- data/spec/scope_spec.rb +79 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +13 -0
- metadata +290 -0
data/spec/bson_spec.rb
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe "BSON for Mongo (BSON)" do
|
|
4
|
+
describe "#decode" do
|
|
5
|
+
it "just returns the json if the :raw_json option is used" do
|
|
6
|
+
hash = {}
|
|
7
|
+
MongoDoc::BSON.should_not_receive(:bson_create)
|
|
8
|
+
MongoDoc::BSON.decode(hash, :raw_json => true).should == hash
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "calls bson_create if parameter is a hash" do
|
|
12
|
+
hash = {}
|
|
13
|
+
options = {:option => true}
|
|
14
|
+
MongoDoc::BSON.should_receive(:bson_create).with(hash, options)
|
|
15
|
+
MongoDoc::BSON.decode(hash, options)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "if parameter is an array, it calls array_create" do
|
|
19
|
+
array = []
|
|
20
|
+
options = {:option => true}
|
|
21
|
+
MongoDoc::BSON.should_receive(:array_create).with(array, options)
|
|
22
|
+
MongoDoc::BSON.decode(array, options)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "returns the json value as is if the parameter is not a hash or array" do
|
|
26
|
+
["", 1, 1.5, true, false, nil].each do |type_value|
|
|
27
|
+
MongoDoc::BSON.decode(type_value).should == type_value
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "#array_create" do
|
|
33
|
+
it "calls decode for each element" do
|
|
34
|
+
first = 1
|
|
35
|
+
array = [first]
|
|
36
|
+
options = {:option => true}
|
|
37
|
+
MongoDoc::BSON.should_receive(:decode).with(first, options)
|
|
38
|
+
MongoDoc::BSON.array_create(array, options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "just returns the array if the :raw_json option is used" do
|
|
42
|
+
hash = {'key' => 'value', MongoDoc::BSON::CLASS_KEY => 'Date'}
|
|
43
|
+
array = [hash]
|
|
44
|
+
MongoDoc::BSON.should_not_receive(:decode)
|
|
45
|
+
MongoDoc::BSON.array_create(array, :raw_json => true).should == array
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe "#bson_create" do
|
|
50
|
+
it "leaves a simple hash intact" do
|
|
51
|
+
hash = {}
|
|
52
|
+
MongoDoc::BSON.bson_create(hash).should == hash
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "a class hash extracts the class, and calls class.bson_create" do
|
|
56
|
+
base_hash = {'key' => 'value'}
|
|
57
|
+
bson_hash = base_hash.merge(MongoDoc::BSON::CLASS_KEY => 'Date')
|
|
58
|
+
Date.should_receive(:bson_create).with(base_hash, {})
|
|
59
|
+
MongoDoc::BSON.bson_create(bson_hash)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "ignores a class hash when the :raw_json option is used" do
|
|
63
|
+
hash = {'key' => 'value', MongoDoc::BSON::CLASS_KEY => 'Date'}
|
|
64
|
+
MongoDoc::BSON.bson_create(hash, :raw_json => true).should == hash
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "Hash" do
|
|
69
|
+
it "#to_bson returns the hash" do
|
|
70
|
+
hash = {'key' => 1}
|
|
71
|
+
hash.to_bson.should == hash
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "#to_bson returns the hash with symbol keys as strings" do
|
|
75
|
+
{:key => 1}.to_bson.should == {"key" => 1}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it "decodes to a hash" do
|
|
79
|
+
hash = {'key' => 1}
|
|
80
|
+
MongoDoc::BSON.decode(hash.to_bson).should == hash
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "decodes the values of the hash" do
|
|
84
|
+
hash = {'key' => {'subkey' => Date.today}}
|
|
85
|
+
MongoDoc::BSON.decode(hash.to_bson).should == hash
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe "Array" do
|
|
90
|
+
it "#to_bson returns the array" do
|
|
91
|
+
array = ['string', 1]
|
|
92
|
+
array.to_bson.should == array
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "#to_bson iterates over its elements" do
|
|
96
|
+
array = []
|
|
97
|
+
array.should_receive(:map)
|
|
98
|
+
array.to_bson
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "decodes to an array" do
|
|
102
|
+
array = ['string', 1]
|
|
103
|
+
MongoDoc::BSON.decode(array.to_bson).should == array
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "Extensions to core classes" do
|
|
108
|
+
it "#to_bson for objects that are BSON native return themselves" do
|
|
109
|
+
[true, false, nil, 1.0, 1, /regexp/, 'string', :symbol, Time.now].each do |native|
|
|
110
|
+
native.to_bson.should == native
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "objects that are BSON native decode to themselves" do
|
|
115
|
+
[true, false, nil, 1.0, 1, /regexp/, 'string', :symbol, Time.now].each do |native|
|
|
116
|
+
hash = {'native' => native}
|
|
117
|
+
MongoDoc::BSON.decode(hash.to_bson).should == hash
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "Date#to_bson returns a date hash" do
|
|
122
|
+
date = Date.today
|
|
123
|
+
date.to_bson.should == {MongoDoc::BSON::CLASS_KEY => "Date", "dt" => date.strftime, "sg" => date.respond_to?(:start) ? date.start : date.sg}
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "roundtrips Date" do
|
|
127
|
+
date = Date.today
|
|
128
|
+
MongoDoc::BSON.decode(date.to_bson).should == date
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "DateTime#to_bson returns a datetime hash" do
|
|
132
|
+
datetime = DateTime.now
|
|
133
|
+
datetime.to_bson.should == {MongoDoc::BSON::CLASS_KEY => "DateTime", "dt" => datetime.strftime, "sg" => datetime.respond_to?(:start) ? datetime.start : datetime.sg}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "roundtrips DateTime" do
|
|
137
|
+
datetime = DateTime.now
|
|
138
|
+
MongoDoc::BSON.decode(datetime.to_bson).to_s.should == datetime.to_s
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
describe "Mongo Classes" do
|
|
143
|
+
[Mongo::ObjectID.new, Mongo::DBRef.new('ns', 1), Mongo::Code.new('code'), Mongo::Binary.new].each do |obj|
|
|
144
|
+
it "#to_bson for #{obj.class.name} returns self" do
|
|
145
|
+
obj.to_bson.should == obj
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "objects of type #{obj.class.name} decode to themselves" do
|
|
149
|
+
hash = {"mongo" => obj}
|
|
150
|
+
MongoDoc::BSON.decode(hash.to_bson)["mongo"].should == obj
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe "Extensions to Object" do
|
|
156
|
+
class Simple
|
|
157
|
+
attr_accessor :value
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
class Complex
|
|
161
|
+
attr_accessor :array_of_simple
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
before do
|
|
165
|
+
@value1 = 'value1'
|
|
166
|
+
@simple1 = Simple.new
|
|
167
|
+
@simple1.value = @value1
|
|
168
|
+
@value2 = 'value2'
|
|
169
|
+
@simple2 = Simple.new
|
|
170
|
+
@simple2.value = @value2
|
|
171
|
+
@complex = Complex.new
|
|
172
|
+
@complex.array_of_simple = [@simple1, @simple2]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "renders a json representation of a simple object" do
|
|
176
|
+
@simple1.to_bson.should be_bson_eql({MongoDoc::BSON::CLASS_KEY => Simple.name, "value" => @value1})
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "renders a json representation of an object with embedded objects" do
|
|
180
|
+
@complex.to_bson.should be_bson_eql({MongoDoc::BSON::CLASS_KEY => Complex.name, "array_of_simple" => [@simple1.to_bson, @simple2.to_bson]})
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "ignores a class hash when the :raw_json option is used" do
|
|
184
|
+
Complex.bson_create(@complex.to_bson.except(MongoDoc::BSON::CLASS_KEY), :raw_json => true).array_of_simple.first.should == @simple1.to_bson
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "roundtrips the object" do
|
|
188
|
+
MongoDoc::BSON.decode(@complex.to_bson).should be_kind_of(Complex)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "allows for embedded arrays of objects" do
|
|
192
|
+
obj = MongoDoc::BSON.decode(@complex.to_bson)
|
|
193
|
+
obj.array_of_simple.each {|o| o.should be_kind_of(Simple)}
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
describe "MongoDoc::Collection" do
|
|
4
|
+
|
|
5
|
+
let(:mongo_collection) { stub('collection') }
|
|
6
|
+
|
|
7
|
+
it ".new delegates to .mongo_collection" do
|
|
8
|
+
name = 'collection_name'
|
|
9
|
+
MongoDoc::Collection.should_receive(:mongo_collection).with(name).and_return(mongo_collection)
|
|
10
|
+
MongoDoc::Collection.new(name)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "with the underlying Mongo::Collection" do
|
|
14
|
+
|
|
15
|
+
let(:collection) do
|
|
16
|
+
MongoDoc::Collection.stub(:mongo_collection).and_return(mongo_collection)
|
|
17
|
+
MongoDoc::Collection.new('collection_name')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
%w([] clear count create_index db distinct drop drop_index drop_indexes group hint index_information map_reduce mapreduce name options pk_factory remove rename size).each do |delegated_method|
|
|
21
|
+
it "delegates #{delegated_method} to the Mongo::Collection" do
|
|
22
|
+
mongo_collection.should_receive(delegated_method)
|
|
23
|
+
collection.send(delegated_method)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "#find" do
|
|
28
|
+
let(:cursor) { MongoDoc::Cursor.new(collection, stub('cursor', :close => nil)) }
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
collection.stub(:wrapped_cursor).and_return(cursor)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "wraps the cursor" do
|
|
35
|
+
query = {'sample' => 'data'}
|
|
36
|
+
options = { :limit => 1}
|
|
37
|
+
collection.should_receive(:wrapped_cursor).with(query, options).and_return(cursor)
|
|
38
|
+
collection.find(query, options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "calls the block with a wrapped cursor" do
|
|
42
|
+
collection.find {|c| @result = c}
|
|
43
|
+
@result.should == cursor
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context "#find_one" do
|
|
48
|
+
let(:bson) { stub('bson') }
|
|
49
|
+
|
|
50
|
+
before do
|
|
51
|
+
mongo_collection.stub(:find_one).and_return(bson)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "delegates to the Mongo::Collection" do
|
|
55
|
+
spec = { 'sample' => 'data' }
|
|
56
|
+
options = {:limit => 1}
|
|
57
|
+
mongo_collection.should_receive(:find_one).with(spec, options)
|
|
58
|
+
collection.find_one(spec, options)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "converts the result back from bson" do
|
|
62
|
+
MongoDoc::BSON.should_receive(:decode).with(bson)
|
|
63
|
+
collection.find_one({ 'sample' => 'data' })
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "returns the converted result" do
|
|
67
|
+
obj = stub('obj')
|
|
68
|
+
MongoDoc::BSON.stub(:decode).and_return(obj)
|
|
69
|
+
collection.find_one({ 'sample' => 'data' }).should == obj
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "returns nil if the delegate returns nil" do
|
|
73
|
+
mongo_collection.stub(:find_one)
|
|
74
|
+
collection.find_one({ 'sample' => 'data' }).should be_nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context "#insert" do
|
|
79
|
+
let(:doc) { {'sample' => 'data'} }
|
|
80
|
+
|
|
81
|
+
it "delegates to the Mongo::Collection" do
|
|
82
|
+
options = {:safe => false}
|
|
83
|
+
mongo_collection.should_receive(:insert).with(doc, options)
|
|
84
|
+
collection.insert(doc, options)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "converts the doc_or_docs to bson" do
|
|
88
|
+
doc.should_receive(:to_bson)
|
|
89
|
+
mongo_collection.stub(:insert)
|
|
90
|
+
collection.insert(doc, options)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "returns the delegates result" do
|
|
94
|
+
result = 'result'
|
|
95
|
+
mongo_collection.stub(:insert).and_return(result)
|
|
96
|
+
collection.insert(doc).should == result
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "#save" do
|
|
101
|
+
let(:doc) { {'sample' => 'data'} }
|
|
102
|
+
|
|
103
|
+
it "delegates to the Mongo::Collection" do
|
|
104
|
+
options = {:safe => false}
|
|
105
|
+
mongo_collection.should_receive(:save).with(doc, options)
|
|
106
|
+
collection.save(doc, options)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "converts the doc to bson" do
|
|
110
|
+
doc.should_receive(:to_bson)
|
|
111
|
+
mongo_collection.stub(:save)
|
|
112
|
+
collection.save(doc)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "returns the delegates result" do
|
|
116
|
+
result = 'result'
|
|
117
|
+
mongo_collection.stub(:save).and_return(result)
|
|
118
|
+
collection.save(doc).should == result
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context "#update" do
|
|
123
|
+
let(:spec) { {'sample' => 'old'} }
|
|
124
|
+
|
|
125
|
+
let(:doc) { {'sample' => 'data'} }
|
|
126
|
+
|
|
127
|
+
let(:options) { {:safe => false} }
|
|
128
|
+
|
|
129
|
+
before do
|
|
130
|
+
collection.stub(:last_error).and_return('updatedExisting' => true)
|
|
131
|
+
mongo_collection.stub(:update)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "delegates to the Mongo::Collection" do
|
|
135
|
+
mongo_collection.should_receive(:update).with(spec, doc, options)
|
|
136
|
+
collection.update(spec, doc, options)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "converts the doc to bson" do
|
|
140
|
+
doc.should_receive(:to_bson)
|
|
141
|
+
collection.update(spec, doc, options)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it "gets the last error from the database" do
|
|
145
|
+
collection.should_receive(:last_error)
|
|
146
|
+
collection.update(spec, doc, options)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "returns the updateExisting value of get last error" do
|
|
150
|
+
result = 'check'
|
|
151
|
+
collection.stub(:last_error).and_return({'updatedExisting' => result})
|
|
152
|
+
collection.update(spec, doc, options).should == result
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "returns false otherwise" do
|
|
156
|
+
collection.stub(:last_error)
|
|
157
|
+
collection.update(spec, doc, options).should be_false
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
2
|
+
|
|
3
|
+
# Resets for testing
|
|
4
|
+
module MongoDoc
|
|
5
|
+
module Connection
|
|
6
|
+
|
|
7
|
+
def reset
|
|
8
|
+
@config_path = nil
|
|
9
|
+
@configuration = nil
|
|
10
|
+
@connection = nil
|
|
11
|
+
@database = nil
|
|
12
|
+
@host = nil
|
|
13
|
+
@name = nil
|
|
14
|
+
@options = nil
|
|
15
|
+
@port = nil
|
|
16
|
+
@strict = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "MongoDoc::Connection.Connections" do
|
|
23
|
+
|
|
24
|
+
context "Non-rails environment" do
|
|
25
|
+
|
|
26
|
+
it "does not see Rails" do
|
|
27
|
+
Object.const_defined?('Rails').should be_false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "default the configuration location to './mongodb.yml'" do
|
|
31
|
+
MongoDoc::Connection.config_path.should == './mongodb.yml'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "without a configuration" do
|
|
35
|
+
let(:connection) { stub('connection') }
|
|
36
|
+
|
|
37
|
+
before do
|
|
38
|
+
MongoDoc::Connection.reset
|
|
39
|
+
MongoDoc::Connection.stub(:connect).and_return(connection)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "creates a default connection" do
|
|
43
|
+
MongoDoc::Connection.should_receive(:connect).and_return(connection)
|
|
44
|
+
MongoDoc::Connection.connection
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "creates a default database with strict false" do
|
|
48
|
+
connection.should_receive(:db).with("mongo_doc", :strict => false)
|
|
49
|
+
MongoDoc::Connection.database
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "Rails environment" do
|
|
55
|
+
|
|
56
|
+
module FauxRails
|
|
57
|
+
extend self
|
|
58
|
+
|
|
59
|
+
def env
|
|
60
|
+
'development'
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def root
|
|
64
|
+
Pathname.new('rails_root')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
before do
|
|
69
|
+
Object.const_set('Rails', FauxRails)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
after do
|
|
73
|
+
Object.send(:remove_const, 'Rails')
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "sees Rails" do
|
|
77
|
+
Object.const_defined?('Rails').should be_true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "default the configuration location to Rails.root + '/config/mongodb.yml'" do
|
|
81
|
+
MongoDoc::Connection.config_path.should == FauxRails.root + 'config/mongodb.yml'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "without a configuration" do
|
|
85
|
+
let(:connection) { stub('connection') }
|
|
86
|
+
|
|
87
|
+
before do
|
|
88
|
+
MongoDoc::Connection.reset
|
|
89
|
+
MongoDoc::Connection.stub(:connect).and_return(connection)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "creates a default connection" do
|
|
93
|
+
MongoDoc::Connection.should_receive(:connect).and_return(connection)
|
|
94
|
+
MongoDoc::Connection.connection
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "creates a default database with strict false" do
|
|
98
|
+
connection.should_receive(:db).with("rails_root_development", :strict => false)
|
|
99
|
+
MongoDoc::Connection.database
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context ".verify_server_version" do
|
|
105
|
+
let(:connection) { stub('connection') }
|
|
106
|
+
|
|
107
|
+
it "raises when the server version is unsupported" do
|
|
108
|
+
connection.stub(:server_version).and_return(Mongo::ServerVersion.new('1.3.1'))
|
|
109
|
+
lambda { MongoDoc::Connection.send(:verify_server_version, connection) }.should raise_error(MongoDoc::UnsupportedServerVersionError)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "returns when the server version is supported" do
|
|
113
|
+
connection.stub(:server_version).and_return(Mongo::ServerVersion.new('1.3.2'))
|
|
114
|
+
lambda { MongoDoc::Connection.send(:verify_server_version, connection) }.should_not raise_error(MongoDoc::UnsupportedServerVersionError)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe ".connect" do
|
|
119
|
+
let(:connection) { stub('connection') }
|
|
120
|
+
|
|
121
|
+
before do
|
|
122
|
+
MongoDoc::Connection.stub(:verify_server_version)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "creates a Mongo::Connection" do
|
|
126
|
+
host = 'host'
|
|
127
|
+
port = 'port'
|
|
128
|
+
options = 'options'
|
|
129
|
+
MongoDoc::Connection.stub(:host).and_return(host)
|
|
130
|
+
MongoDoc::Connection.stub(:port).and_return(port)
|
|
131
|
+
MongoDoc::Connection.stub(:options).and_return(options)
|
|
132
|
+
Mongo::Connection.should_receive(:new).with(host, port, options).and_return(connection)
|
|
133
|
+
MongoDoc::Connection.send(:connect)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it "raises NoConnectionError if the connection fails" do
|
|
137
|
+
Mongo::Connection.stub(:new).and_return(nil)
|
|
138
|
+
lambda { MongoDoc::Connection.send(:connect) }.should raise_error(MongoDoc::NoConnectionError)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "verifies the connection version" do
|
|
142
|
+
Mongo::Connection.stub(:new).and_return(connection)
|
|
143
|
+
MongoDoc::Connection.should_receive(:verify_server_version)
|
|
144
|
+
MongoDoc::Connection.send(:connect)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|