mongo_doc_rails2 0.6.1

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.
Files changed (142) hide show
  1. data/.document +5 -0
  2. data/.gitignore +8 -0
  3. data/HISTORY.md +11 -0
  4. data/LICENSE +20 -0
  5. data/README.textile +185 -0
  6. data/Rakefile +188 -0
  7. data/TODO +40 -0
  8. data/VERSION +1 -0
  9. data/data/.gitignore +2 -0
  10. data/examples/simple_document.rb +46 -0
  11. data/examples/simple_object.rb +34 -0
  12. data/features/collections.feature +9 -0
  13. data/features/embed_hash.feature +16 -0
  14. data/features/finders.feature +76 -0
  15. data/features/indexes.feature +28 -0
  16. data/features/mongodb.yml +7 -0
  17. data/features/mongodoc_base.feature +128 -0
  18. data/features/new_record.feature +36 -0
  19. data/features/partial_updates.feature +95 -0
  20. data/features/removing_documents.feature +68 -0
  21. data/features/saving_an_object.feature +15 -0
  22. data/features/scopes.feature +66 -0
  23. data/features/step_definitions/collection_steps.rb +17 -0
  24. data/features/step_definitions/document_steps.rb +149 -0
  25. data/features/step_definitions/documents.rb +40 -0
  26. data/features/step_definitions/embed_hash_steps.rb +6 -0
  27. data/features/step_definitions/finder_steps.rb +15 -0
  28. data/features/step_definitions/index_steps.rb +10 -0
  29. data/features/step_definitions/json_steps.rb +9 -0
  30. data/features/step_definitions/object_steps.rb +50 -0
  31. data/features/step_definitions/objects.rb +24 -0
  32. data/features/step_definitions/partial_update_steps.rb +31 -0
  33. data/features/step_definitions/query_steps.rb +66 -0
  34. data/features/step_definitions/removing_documents_steps.rb +14 -0
  35. data/features/step_definitions/scope_steps.rb +18 -0
  36. data/features/step_definitions/string_casting_steps.rb +29 -0
  37. data/features/step_definitions/util_steps.rb +7 -0
  38. data/features/string_casting.feature +10 -0
  39. data/features/support/support.rb +10 -0
  40. data/features/using_criteria.feature +142 -0
  41. data/lib/mongo_doc.rb +12 -0
  42. data/lib/mongo_doc/associations.rb +109 -0
  43. data/lib/mongo_doc/associations/collection_proxy.rb +121 -0
  44. data/lib/mongo_doc/associations/document_proxy.rb +65 -0
  45. data/lib/mongo_doc/associations/hash_proxy.rb +102 -0
  46. data/lib/mongo_doc/associations/proxy_base.rb +48 -0
  47. data/lib/mongo_doc/attributes.rb +84 -0
  48. data/lib/mongo_doc/bson.rb +31 -0
  49. data/lib/mongo_doc/collection.rb +82 -0
  50. data/lib/mongo_doc/connection.rb +88 -0
  51. data/lib/mongo_doc/contexts.rb +31 -0
  52. data/lib/mongo_doc/contexts/ids.rb +41 -0
  53. data/lib/mongo_doc/contexts/mongo.rb +272 -0
  54. data/lib/mongo_doc/criteria.rb +70 -0
  55. data/lib/mongo_doc/cursor.rb +32 -0
  56. data/lib/mongo_doc/document.rb +205 -0
  57. data/lib/mongo_doc/ext.rb +16 -0
  58. data/lib/mongo_doc/ext/array.rb +5 -0
  59. data/lib/mongo_doc/ext/binary.rb +7 -0
  60. data/lib/mongo_doc/ext/boolean_class.rb +17 -0
  61. data/lib/mongo_doc/ext/date.rb +19 -0
  62. data/lib/mongo_doc/ext/date_time.rb +17 -0
  63. data/lib/mongo_doc/ext/dbref.rb +7 -0
  64. data/lib/mongo_doc/ext/hash.rb +7 -0
  65. data/lib/mongo_doc/ext/min_max_keys.rb +13 -0
  66. data/lib/mongo_doc/ext/nil_class.rb +5 -0
  67. data/lib/mongo_doc/ext/numeric.rb +17 -0
  68. data/lib/mongo_doc/ext/object.rb +19 -0
  69. data/lib/mongo_doc/ext/object_id.rb +7 -0
  70. data/lib/mongo_doc/ext/regexp.rb +5 -0
  71. data/lib/mongo_doc/ext/string.rb +5 -0
  72. data/lib/mongo_doc/ext/symbol.rb +5 -0
  73. data/lib/mongo_doc/ext/time.rb +9 -0
  74. data/lib/mongo_doc/finders.rb +38 -0
  75. data/lib/mongo_doc/index.rb +46 -0
  76. data/lib/mongo_doc/matchers.rb +35 -0
  77. data/lib/mongo_doc/root.rb +26 -0
  78. data/lib/mongo_doc/scope.rb +64 -0
  79. data/lib/mongo_doc/validations.rb +12 -0
  80. data/lib/mongo_doc/validations/macros.rb +11 -0
  81. data/lib/mongo_doc/validations/validates_embedded.rb +13 -0
  82. data/lib/mongoid/contexts/enumerable.rb +151 -0
  83. data/lib/mongoid/contexts/paging.rb +42 -0
  84. data/lib/mongoid/criteria.rb +239 -0
  85. data/lib/mongoid/criterion/complex.rb +21 -0
  86. data/lib/mongoid/criterion/exclusion.rb +65 -0
  87. data/lib/mongoid/criterion/inclusion.rb +93 -0
  88. data/lib/mongoid/criterion/optional.rb +136 -0
  89. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  90. data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
  91. data/lib/mongoid/matchers/all.rb +11 -0
  92. data/lib/mongoid/matchers/default.rb +26 -0
  93. data/lib/mongoid/matchers/exists.rb +13 -0
  94. data/lib/mongoid/matchers/gt.rb +11 -0
  95. data/lib/mongoid/matchers/gte.rb +11 -0
  96. data/lib/mongoid/matchers/in.rb +11 -0
  97. data/lib/mongoid/matchers/lt.rb +11 -0
  98. data/lib/mongoid/matchers/lte.rb +11 -0
  99. data/lib/mongoid/matchers/ne.rb +11 -0
  100. data/lib/mongoid/matchers/nin.rb +11 -0
  101. data/lib/mongoid/matchers/size.rb +11 -0
  102. data/mongo_doc_rails2.gemspec +237 -0
  103. data/mongod.example.yml +2 -0
  104. data/mongodb.example.yml +14 -0
  105. data/perf/mongo_doc_object.rb +83 -0
  106. data/perf/mongo_document.rb +84 -0
  107. data/perf/ruby_driver.rb +49 -0
  108. data/script/console +8 -0
  109. data/spec/array_including_argument_matcher.rb +62 -0
  110. data/spec/associations/collection_proxy_spec.rb +233 -0
  111. data/spec/associations/document_proxy_spec.rb +45 -0
  112. data/spec/associations/hash_proxy_spec.rb +181 -0
  113. data/spec/associations/proxy_base_spec.rb +92 -0
  114. data/spec/associations_spec.rb +218 -0
  115. data/spec/attributes_accessor_spec.rb +33 -0
  116. data/spec/attributes_spec.rb +145 -0
  117. data/spec/bson_matchers.rb +54 -0
  118. data/spec/bson_spec.rb +196 -0
  119. data/spec/collection_spec.rb +169 -0
  120. data/spec/connection_spec.rb +147 -0
  121. data/spec/contexts/ids_spec.rb +49 -0
  122. data/spec/contexts/mongo_spec.rb +235 -0
  123. data/spec/contexts_spec.rb +56 -0
  124. data/spec/criteria_spec.rb +69 -0
  125. data/spec/cursor_spec.rb +91 -0
  126. data/spec/document_ext.rb +9 -0
  127. data/spec/document_spec.rb +553 -0
  128. data/spec/embedded_save_spec.rb +73 -0
  129. data/spec/ext_spec.rb +89 -0
  130. data/spec/finders_spec.rb +61 -0
  131. data/spec/hash_matchers.rb +27 -0
  132. data/spec/index_spec.rb +79 -0
  133. data/spec/matchers_spec.rb +342 -0
  134. data/spec/mongodb.yml +6 -0
  135. data/spec/mongodb_pairs.yml +8 -0
  136. data/spec/new_record_spec.rb +128 -0
  137. data/spec/root_spec.rb +41 -0
  138. data/spec/scope_spec.rb +79 -0
  139. data/spec/spec.opts +2 -0
  140. data/spec/spec_helper.rb +14 -0
  141. data/spec/validations_spec.rb +30 -0
  142. metadata +346 -0
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MongoDoc::Attributes attributes accessor" do
4
+ class AttributesTest
5
+ include MongoDoc::Attributes
6
+
7
+ attr_accessor :name
8
+ attr_accessor :age
9
+ attr_accessor :birthdate, :type => Date
10
+ end
11
+
12
+ context "#attributes" do
13
+ subject do
14
+ AttributesTest.new.attributes
15
+ end
16
+
17
+ it "returns a hash of the given attributes" do
18
+ should have_key(:name)
19
+ should have_key(:age)
20
+ should have_key(:birthdate)
21
+ end
22
+ end
23
+
24
+ context "#attributes=" do
25
+ let(:object) { AttributesTest.new }
26
+
27
+ it "sets attributes from a hash" do
28
+ name = 'name'
29
+ object.attributes = {:name => name}
30
+ object.name.should == name
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MongoDoc::Attributes" do
4
+ class AttributesTest
5
+ include MongoDoc::Attributes
6
+ end
7
+
8
+ it "defines _id attribute" do
9
+ AttributesTest.new.should respond_to(:_id)
10
+ AttributesTest.new.should respond_to(:_id=)
11
+ end
12
+
13
+ context ".key" do
14
+ class AttributeAccessorTest
15
+ include MongoDoc::Attributes
16
+
17
+ key :date, :default => Date.today, :type => Date
18
+ end
19
+
20
+ it "is an alias for attr_accessor" do
21
+ AttributeAccessorTest._keys.should include(:date)
22
+ end
23
+ end
24
+
25
+ context ".attr_accessor" do
26
+ class TestKeys
27
+ include MongoDoc::Attributes
28
+
29
+ attr_accessor :attr1, :attr2
30
+ end
31
+
32
+ it "adds its arguments to _keys" do
33
+ TestKeys._keys.should == [:attr1, :attr2]
34
+ end
35
+
36
+ describe "accessors" do
37
+ subject do
38
+ TestKeys.new
39
+ end
40
+
41
+ it "has an attr1 reader" do
42
+ should respond_to(:attr1)
43
+ end
44
+
45
+ it "has an attr1 writer" do
46
+ should respond_to(:attr1=)
47
+ end
48
+ end
49
+
50
+ context "default values" do
51
+ class TestDefault
52
+ include MongoDoc::Attributes
53
+
54
+ attr_accessor :with_default, :default => 'value'
55
+ end
56
+
57
+ let(:object) { TestDefault.new }
58
+
59
+ it "uses the default value" do
60
+ object.with_default.should == 'value'
61
+ end
62
+
63
+ it "only uses the default value once" do
64
+ object.with_default.should == 'value'
65
+ class << object
66
+ def _default_with_default
67
+ 'other value'
68
+ end
69
+ end
70
+ object.with_default.should == 'value'
71
+ end
72
+
73
+ it "does not set the default value if the setter is invoked first" do
74
+ object.with_default = nil
75
+ object.with_default.should be_nil
76
+ end
77
+ end
78
+
79
+ context "specified type" do
80
+ class TestType
81
+ include MongoDoc::Attributes
82
+
83
+ attr_accessor :birthdate, :type => Date
84
+ end
85
+
86
+ let(:object) { TestType.new }
87
+
88
+ it "does not call Type.cast_from_string when the set value is not a string" do
89
+ Date.should_not_receive :cast_from_string
90
+ object.birthdate = Date.today
91
+ end
92
+
93
+ context "when the accessor is set with a string" do
94
+ let(:date) { Date.today }
95
+
96
+ it "delegates to Type.cast_from_string to set the value" do
97
+ Date.should_receive(:cast_from_string).with(date.to_s)
98
+ object.birthdate = date.to_s
99
+ end
100
+
101
+ it "sets the value to the result of the case" do
102
+ object.birthdate = date.to_s
103
+ object.birthdate.should == date
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "used with inheritance" do
109
+ class TestParent
110
+ include MongoDoc::Attributes
111
+
112
+ attr_accessor :parent_attr
113
+ end
114
+
115
+ class TestChild < TestParent
116
+ attr_accessor :child_attr
117
+ end
118
+
119
+ it "has its own keys" do
120
+ TestChild._keys.should include(:child_attr)
121
+ end
122
+
123
+ it "has the keys from the parent class" do
124
+ TestChild._keys.should include(*TestParent._keys)
125
+ end
126
+
127
+ it "does not add keys to the parent class" do
128
+ TestParent._keys.should_not include(:child_attr)
129
+ end
130
+ end
131
+ end
132
+
133
+ context "._attributes" do
134
+ class TestHasOneDoc
135
+ include MongoDoc::Document
136
+
137
+ attr_accessor :key
138
+ embed :embed
139
+ end
140
+
141
+ it "is _keys + _associations" do
142
+ TestHasOneDoc._attributes.should == TestHasOneDoc._keys + TestHasOneDoc._associations
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,54 @@
1
+ module BsonMatchers
2
+ class BeBsonEql
3
+ def initialize(expected)
4
+ @expected = expected
5
+ end
6
+
7
+ def matches?(target)
8
+ @target = target
9
+ @target == @expected
10
+ end
11
+
12
+ def failure_message
13
+ "expected\...#{@target.inspect}\n" +
14
+ "to be BSON code equivalent to\...#{@expected.inspect}\n" +
15
+ "Difference:\...#{@expected.diff(@target).inspect}"
16
+ end
17
+
18
+ def negative_failure_message
19
+ "expected\...#{@target.inspect}\n" +
20
+ "to be BSON code different from\...#{@expected.inspect}"
21
+ end
22
+ end
23
+
24
+ class BeMongoEql
25
+ def initialize(expected, include_id)
26
+ @include_id = include_id
27
+ @expected = include_id ? expected : expected.except('_id')
28
+ end
29
+
30
+ def matches?(target)
31
+ @target = @include_id ? target : target.except('_id')
32
+ @target == @expected
33
+ end
34
+
35
+ def failure_message
36
+ "expected\...#{@target.inspect}\n" +
37
+ "to be BSON code equivalent to\...#{@expected.inspect}\n" +
38
+ "Difference:\...#{@expected.diff(@target).inspect}"
39
+ end
40
+
41
+ def negative_failure_message
42
+ "expected\...#{@target.inspect}\n" +
43
+ "to be BSON code different from\...#{@expected.inspect}"
44
+ end
45
+ end
46
+
47
+ def be_bson_eql(expected)
48
+ BeBsonEql.new(expected)
49
+ end
50
+
51
+ def be_mongo_eql(expected, include_id = true)
52
+ BeMongoEql.new(expected, include_id)
53
+ end
54
+ end
@@ -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
+ [BSON::ObjectID.new, BSON::DBRef.new('ns', 1), BSON::Code.new('code'), BSON::Binary.new, BSON::MinKey.new, BSON::MaxKey.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,169 @@
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
+ it "has Criteria mixed in" do
21
+ MongoDoc::Criteria.should === collection
22
+ end
23
+
24
+ it "#collection references self for Mongo context" do
25
+ collection.send(:collection).should == collection
26
+ end
27
+
28
+ %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|
29
+ it "delegates #{delegated_method} to the Mongo::Collection" do
30
+ mongo_collection.should_receive(delegated_method)
31
+ collection.send(delegated_method)
32
+ end
33
+ end
34
+
35
+ context "#find" do
36
+ let(:cursor) { MongoDoc::Cursor.new(collection, stub('cursor', :close => nil)) }
37
+
38
+ before do
39
+ collection.stub(:wrapped_cursor).and_return(cursor)
40
+ end
41
+
42
+ it "wraps the cursor" do
43
+ query = {'sample' => 'data'}
44
+ options = { :limit => 1}
45
+ collection.should_receive(:wrapped_cursor).with(query, options).and_return(cursor)
46
+ collection.find(query, options)
47
+ end
48
+
49
+ it "calls the block with a wrapped cursor" do
50
+ collection.find {|c| @result = c}
51
+ @result.should == cursor
52
+ end
53
+ end
54
+
55
+ context "#find_one" do
56
+ let(:bson) { stub('bson') }
57
+
58
+ before do
59
+ mongo_collection.stub(:find_one).and_return(bson)
60
+ end
61
+
62
+ it "delegates to the Mongo::Collection" do
63
+ spec = { 'sample' => 'data' }
64
+ options = {:limit => 1}
65
+ mongo_collection.should_receive(:find_one).with(spec, options)
66
+ collection.find_one(spec, options)
67
+ end
68
+
69
+ it "converts the result back from bson" do
70
+ MongoDoc::BSON.should_receive(:decode).with(bson)
71
+ collection.find_one({ 'sample' => 'data' })
72
+ end
73
+
74
+ it "returns the converted result" do
75
+ obj = stub('obj')
76
+ MongoDoc::BSON.stub(:decode).and_return(obj)
77
+ collection.find_one({ 'sample' => 'data' }).should == obj
78
+ end
79
+
80
+ it "returns nil if the delegate returns nil" do
81
+ mongo_collection.stub(:find_one)
82
+ collection.find_one({ 'sample' => 'data' }).should be_nil
83
+ end
84
+ end
85
+
86
+ context "#insert" do
87
+ let(:doc) { {'sample' => 'data'} }
88
+
89
+ it "delegates to the Mongo::Collection" do
90
+ options = {:safe => false}
91
+ mongo_collection.should_receive(:insert).with(doc, options)
92
+ collection.insert(doc, options)
93
+ end
94
+
95
+ it "converts the doc_or_docs to bson" do
96
+ doc.should_receive(:to_bson)
97
+ mongo_collection.stub(:insert)
98
+ collection.insert(doc, options)
99
+ end
100
+
101
+ it "returns the delegates result" do
102
+ result = 'result'
103
+ mongo_collection.stub(:insert).and_return(result)
104
+ collection.insert(doc).should == result
105
+ end
106
+ end
107
+
108
+ context "#save" do
109
+ let(:doc) { {'sample' => 'data'} }
110
+
111
+ it "delegates to the Mongo::Collection" do
112
+ options = {:safe => false}
113
+ mongo_collection.should_receive(:save).with(doc, options)
114
+ collection.save(doc, options)
115
+ end
116
+
117
+ it "converts the doc to bson" do
118
+ doc.should_receive(:to_bson)
119
+ mongo_collection.stub(:save)
120
+ collection.save(doc)
121
+ end
122
+
123
+ it "returns the delegates result" do
124
+ result = 'result'
125
+ mongo_collection.stub(:save).and_return(result)
126
+ collection.save(doc).should == result
127
+ end
128
+ end
129
+
130
+ context "#update" do
131
+ let(:spec) { {'sample' => 'old'} }
132
+
133
+ let(:doc) { {'sample' => 'data'} }
134
+
135
+ let(:options) { {:safe => false} }
136
+
137
+ before do
138
+ collection.stub(:last_error).and_return('updatedExisting' => true)
139
+ mongo_collection.stub(:update)
140
+ end
141
+
142
+ it "delegates to the Mongo::Collection" do
143
+ mongo_collection.should_receive(:update).with(spec, doc, options)
144
+ collection.update(spec, doc, options)
145
+ end
146
+
147
+ it "converts the doc to bson" do
148
+ doc.should_receive(:to_bson)
149
+ collection.update(spec, doc, options)
150
+ end
151
+
152
+ it "gets the last error from the database" do
153
+ collection.should_receive(:last_error)
154
+ collection.update(spec, doc, options)
155
+ end
156
+
157
+ it "returns the updateExisting value of get last error" do
158
+ result = 'check'
159
+ collection.stub(:last_error).and_return({'updatedExisting' => result})
160
+ collection.update(spec, doc, options).should == result
161
+ end
162
+
163
+ it "returns false otherwise" do
164
+ collection.stub(:last_error)
165
+ collection.update(spec, doc, options).should be_false
166
+ end
167
+ end
168
+ end
169
+ end