mongoid-locomotive 2.0.0.beta9

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 (274) hide show
  1. data/MIT_LICENSE +20 -0
  2. data/README.rdoc +47 -0
  3. data/lib/mongoid.rb +141 -0
  4. data/lib/mongoid/associations.rb +306 -0
  5. data/lib/mongoid/associations/embedded_in.rb +74 -0
  6. data/lib/mongoid/associations/embeds_many.rb +280 -0
  7. data/lib/mongoid/associations/embeds_one.rb +97 -0
  8. data/lib/mongoid/associations/foreign_key.rb +35 -0
  9. data/lib/mongoid/associations/meta_data.rb +38 -0
  10. data/lib/mongoid/associations/options.rb +62 -0
  11. data/lib/mongoid/associations/proxy.rb +33 -0
  12. data/lib/mongoid/associations/referenced_in.rb +59 -0
  13. data/lib/mongoid/associations/references_many.rb +245 -0
  14. data/lib/mongoid/associations/references_many_as_array.rb +78 -0
  15. data/lib/mongoid/associations/references_one.rb +99 -0
  16. data/lib/mongoid/atomicity.rb +55 -0
  17. data/lib/mongoid/attributes.rb +242 -0
  18. data/lib/mongoid/callbacks.rb +21 -0
  19. data/lib/mongoid/collection.rb +120 -0
  20. data/lib/mongoid/collections.rb +71 -0
  21. data/lib/mongoid/collections/cyclic_iterator.rb +34 -0
  22. data/lib/mongoid/collections/master.rb +29 -0
  23. data/lib/mongoid/collections/operations.rb +41 -0
  24. data/lib/mongoid/collections/slaves.rb +45 -0
  25. data/lib/mongoid/components.rb +34 -0
  26. data/lib/mongoid/config.rb +263 -0
  27. data/lib/mongoid/contexts.rb +24 -0
  28. data/lib/mongoid/contexts/enumerable.rb +156 -0
  29. data/lib/mongoid/contexts/ids.rb +25 -0
  30. data/lib/mongoid/contexts/mongo.rb +285 -0
  31. data/lib/mongoid/contexts/paging.rb +50 -0
  32. data/lib/mongoid/criteria.rb +248 -0
  33. data/lib/mongoid/criterion/complex.rb +21 -0
  34. data/lib/mongoid/criterion/exclusion.rb +65 -0
  35. data/lib/mongoid/criterion/inclusion.rb +110 -0
  36. data/lib/mongoid/criterion/optional.rb +189 -0
  37. data/lib/mongoid/cursor.rb +81 -0
  38. data/lib/mongoid/deprecation.rb +21 -0
  39. data/lib/mongoid/dirty.rb +252 -0
  40. data/lib/mongoid/document.rb +210 -0
  41. data/lib/mongoid/errors.rb +131 -0
  42. data/lib/mongoid/extensions.rb +115 -0
  43. data/lib/mongoid/extensions/array/accessors.rb +17 -0
  44. data/lib/mongoid/extensions/array/assimilation.rb +26 -0
  45. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  46. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  47. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  48. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  49. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  50. data/lib/mongoid/extensions/date/conversions.rb +24 -0
  51. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  52. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  53. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  54. data/lib/mongoid/extensions/hash/accessors.rb +42 -0
  55. data/lib/mongoid/extensions/hash/assimilation.rb +40 -0
  56. data/lib/mongoid/extensions/hash/conversions.rb +42 -0
  57. data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
  58. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  59. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  60. data/lib/mongoid/extensions/nil/assimilation.rb +17 -0
  61. data/lib/mongoid/extensions/object/conversions.rb +21 -0
  62. data/lib/mongoid/extensions/objectid/conversions.rb +15 -0
  63. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  64. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  65. data/lib/mongoid/extensions/string/conversions.rb +15 -0
  66. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  67. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  68. data/lib/mongoid/extensions/time_conversions.rb +35 -0
  69. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  70. data/lib/mongoid/extras.rb +61 -0
  71. data/lib/mongoid/factory.rb +20 -0
  72. data/lib/mongoid/field.rb +83 -0
  73. data/lib/mongoid/fields.rb +62 -0
  74. data/lib/mongoid/finders.rb +145 -0
  75. data/lib/mongoid/hierarchy.rb +74 -0
  76. data/lib/mongoid/identity.rb +47 -0
  77. data/lib/mongoid/indexes.rb +27 -0
  78. data/lib/mongoid/javascript.rb +21 -0
  79. data/lib/mongoid/javascript/functions.yml +37 -0
  80. data/lib/mongoid/logger.rb +19 -0
  81. data/lib/mongoid/matchers.rb +35 -0
  82. data/lib/mongoid/matchers/all.rb +11 -0
  83. data/lib/mongoid/matchers/default.rb +26 -0
  84. data/lib/mongoid/matchers/exists.rb +13 -0
  85. data/lib/mongoid/matchers/gt.rb +11 -0
  86. data/lib/mongoid/matchers/gte.rb +11 -0
  87. data/lib/mongoid/matchers/in.rb +11 -0
  88. data/lib/mongoid/matchers/lt.rb +11 -0
  89. data/lib/mongoid/matchers/lte.rb +11 -0
  90. data/lib/mongoid/matchers/ne.rb +11 -0
  91. data/lib/mongoid/matchers/nin.rb +11 -0
  92. data/lib/mongoid/matchers/size.rb +11 -0
  93. data/lib/mongoid/memoization.rb +33 -0
  94. data/lib/mongoid/named_scope.rb +37 -0
  95. data/lib/mongoid/paranoia.rb +106 -0
  96. data/lib/mongoid/paths.rb +61 -0
  97. data/lib/mongoid/persistence.rb +216 -0
  98. data/lib/mongoid/persistence/command.rb +39 -0
  99. data/lib/mongoid/persistence/insert.rb +48 -0
  100. data/lib/mongoid/persistence/insert_embedded.rb +44 -0
  101. data/lib/mongoid/persistence/remove.rb +39 -0
  102. data/lib/mongoid/persistence/remove_all.rb +38 -0
  103. data/lib/mongoid/persistence/remove_embedded.rb +50 -0
  104. data/lib/mongoid/persistence/update.rb +71 -0
  105. data/lib/mongoid/railtie.rb +67 -0
  106. data/lib/mongoid/railties/database.rake +60 -0
  107. data/lib/mongoid/scope.rb +75 -0
  108. data/lib/mongoid/state.rb +32 -0
  109. data/lib/mongoid/timestamps.rb +27 -0
  110. data/lib/mongoid/validations.rb +51 -0
  111. data/lib/mongoid/validations/associated.rb +32 -0
  112. data/lib/mongoid/validations/locale/en.yml +5 -0
  113. data/lib/mongoid/validations/uniqueness.rb +56 -0
  114. data/lib/mongoid/version.rb +4 -0
  115. data/lib/mongoid/versioning.rb +26 -0
  116. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  117. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +24 -0
  118. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  119. data/lib/rails/generators/mongoid/model/templates/model.rb +15 -0
  120. data/lib/rails/generators/mongoid_generator.rb +61 -0
  121. data/spec/integration/mongoid/association_attributes_spec.rb +71 -0
  122. data/spec/integration/mongoid/associations_spec.rb +768 -0
  123. data/spec/integration/mongoid/attributes_spec.rb +59 -0
  124. data/spec/integration/mongoid/callback_spec.rb +33 -0
  125. data/spec/integration/mongoid/contexts/enumerable_spec.rb +33 -0
  126. data/spec/integration/mongoid/criteria_spec.rb +281 -0
  127. data/spec/integration/mongoid/dirty_spec.rb +85 -0
  128. data/spec/integration/mongoid/document_spec.rb +741 -0
  129. data/spec/integration/mongoid/extensions_spec.rb +22 -0
  130. data/spec/integration/mongoid/finders_spec.rb +119 -0
  131. data/spec/integration/mongoid/inheritance_spec.rb +171 -0
  132. data/spec/integration/mongoid/named_scope_spec.rb +58 -0
  133. data/spec/integration/mongoid/paranoia_spec.rb +44 -0
  134. data/spec/integration/mongoid/persistence/update_spec.rb +46 -0
  135. data/spec/integration/mongoid/persistence_spec.rb +311 -0
  136. data/spec/integration/mongoid/validations/uniqueness_spec.rb +206 -0
  137. data/spec/models/account.rb +5 -0
  138. data/spec/models/address.rb +40 -0
  139. data/spec/models/agent.rb +7 -0
  140. data/spec/models/animal.rb +15 -0
  141. data/spec/models/answer.rb +4 -0
  142. data/spec/models/callbacks.rb +47 -0
  143. data/spec/models/category.rb +13 -0
  144. data/spec/models/comment.rb +10 -0
  145. data/spec/models/country_code.rb +6 -0
  146. data/spec/models/employer.rb +5 -0
  147. data/spec/models/favorite.rb +8 -0
  148. data/spec/models/game.rb +9 -0
  149. data/spec/models/inheritance.rb +72 -0
  150. data/spec/models/location.rb +5 -0
  151. data/spec/models/login.rb +6 -0
  152. data/spec/models/mixed_drink.rb +4 -0
  153. data/spec/models/name.rb +13 -0
  154. data/spec/models/namespacing.rb +11 -0
  155. data/spec/models/paranoid_post.rb +18 -0
  156. data/spec/models/parents.rb +32 -0
  157. data/spec/models/patient.rb +15 -0
  158. data/spec/models/person.rb +106 -0
  159. data/spec/models/pet.rb +7 -0
  160. data/spec/models/pet_owner.rb +6 -0
  161. data/spec/models/phone.rb +7 -0
  162. data/spec/models/post.rb +25 -0
  163. data/spec/models/preference.rb +7 -0
  164. data/spec/models/question.rb +8 -0
  165. data/spec/models/survey.rb +6 -0
  166. data/spec/models/translation.rb +5 -0
  167. data/spec/models/user.rb +6 -0
  168. data/spec/models/user_accout.rb +5 -0
  169. data/spec/models/vet_visit.rb +5 -0
  170. data/spec/models/video.rb +5 -0
  171. data/spec/spec_helper.rb +33 -0
  172. data/spec/unit/mongoid/associations/embedded_in_spec.rb +193 -0
  173. data/spec/unit/mongoid/associations/embeds_many_spec.rb +626 -0
  174. data/spec/unit/mongoid/associations/embeds_one_spec.rb +287 -0
  175. data/spec/unit/mongoid/associations/foreign_key_spec.rb +90 -0
  176. data/spec/unit/mongoid/associations/meta_data_spec.rb +110 -0
  177. data/spec/unit/mongoid/associations/options_spec.rb +215 -0
  178. data/spec/unit/mongoid/associations/referenced_in_spec.rb +145 -0
  179. data/spec/unit/mongoid/associations/references_many_as_array_spec.rb +424 -0
  180. data/spec/unit/mongoid/associations/references_many_spec.rb +502 -0
  181. data/spec/unit/mongoid/associations/references_one_spec.rb +204 -0
  182. data/spec/unit/mongoid/associations_spec.rb +688 -0
  183. data/spec/unit/mongoid/atomicity_spec.rb +164 -0
  184. data/spec/unit/mongoid/attributes_spec.rb +646 -0
  185. data/spec/unit/mongoid/callbacks_spec.rb +85 -0
  186. data/spec/unit/mongoid/collection_spec.rb +187 -0
  187. data/spec/unit/mongoid/collections/cyclic_iterator_spec.rb +75 -0
  188. data/spec/unit/mongoid/collections/master_spec.rb +41 -0
  189. data/spec/unit/mongoid/collections/slaves_spec.rb +81 -0
  190. data/spec/unit/mongoid/collections_spec.rb +98 -0
  191. data/spec/unit/mongoid/config_spec.rb +298 -0
  192. data/spec/unit/mongoid/contexts/enumerable_spec.rb +447 -0
  193. data/spec/unit/mongoid/contexts/mongo_spec.rb +703 -0
  194. data/spec/unit/mongoid/contexts_spec.rb +25 -0
  195. data/spec/unit/mongoid/criteria_spec.rb +873 -0
  196. data/spec/unit/mongoid/criterion/complex_spec.rb +17 -0
  197. data/spec/unit/mongoid/criterion/exclusion_spec.rb +121 -0
  198. data/spec/unit/mongoid/criterion/inclusion_spec.rb +274 -0
  199. data/spec/unit/mongoid/criterion/optional_spec.rb +483 -0
  200. data/spec/unit/mongoid/cursor_spec.rb +80 -0
  201. data/spec/unit/mongoid/deprecation_spec.rb +24 -0
  202. data/spec/unit/mongoid/dirty_spec.rb +430 -0
  203. data/spec/unit/mongoid/document_spec.rb +623 -0
  204. data/spec/unit/mongoid/errors_spec.rb +154 -0
  205. data/spec/unit/mongoid/extensions/array/accessors_spec.rb +50 -0
  206. data/spec/unit/mongoid/extensions/array/assimilation_spec.rb +24 -0
  207. data/spec/unit/mongoid/extensions/array/conversions_spec.rb +52 -0
  208. data/spec/unit/mongoid/extensions/array/parentization_spec.rb +20 -0
  209. data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +36 -0
  210. data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
  211. data/spec/unit/mongoid/extensions/boolean/conversions_spec.rb +49 -0
  212. data/spec/unit/mongoid/extensions/date/conversions_spec.rb +145 -0
  213. data/spec/unit/mongoid/extensions/datetime/conversions_spec.rb +14 -0
  214. data/spec/unit/mongoid/extensions/false_class/equality_spec.rb +35 -0
  215. data/spec/unit/mongoid/extensions/float/conversions_spec.rb +61 -0
  216. data/spec/unit/mongoid/extensions/hash/accessors_spec.rb +184 -0
  217. data/spec/unit/mongoid/extensions/hash/assimilation_spec.rb +59 -0
  218. data/spec/unit/mongoid/extensions/hash/conversions_spec.rb +35 -0
  219. data/spec/unit/mongoid/extensions/hash/criteria_helpers_spec.rb +17 -0
  220. data/spec/unit/mongoid/extensions/hash/scoping_spec.rb +14 -0
  221. data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +61 -0
  222. data/spec/unit/mongoid/extensions/nil/assimilation_spec.rb +29 -0
  223. data/spec/unit/mongoid/extensions/object/conversions_spec.rb +44 -0
  224. data/spec/unit/mongoid/extensions/objectid/conversions_spec.rb +22 -0
  225. data/spec/unit/mongoid/extensions/proc/scoping_spec.rb +34 -0
  226. data/spec/unit/mongoid/extensions/set/conversions_spec.rb +21 -0
  227. data/spec/unit/mongoid/extensions/string/conversions_spec.rb +28 -0
  228. data/spec/unit/mongoid/extensions/string/inflections_spec.rb +208 -0
  229. data/spec/unit/mongoid/extensions/symbol/inflections_spec.rb +107 -0
  230. data/spec/unit/mongoid/extensions/time_conversions_spec.rb +186 -0
  231. data/spec/unit/mongoid/extensions/true_class/equality_spec.rb +35 -0
  232. data/spec/unit/mongoid/extras_spec.rb +102 -0
  233. data/spec/unit/mongoid/factory_spec.rb +31 -0
  234. data/spec/unit/mongoid/field_spec.rb +169 -0
  235. data/spec/unit/mongoid/fields_spec.rb +181 -0
  236. data/spec/unit/mongoid/finders_spec.rb +439 -0
  237. data/spec/unit/mongoid/hierarchy_spec.rb +68 -0
  238. data/spec/unit/mongoid/identity_spec.rb +109 -0
  239. data/spec/unit/mongoid/indexes_spec.rb +99 -0
  240. data/spec/unit/mongoid/javascript_spec.rb +48 -0
  241. data/spec/unit/mongoid/logger_spec.rb +38 -0
  242. data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
  243. data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
  244. data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
  245. data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
  246. data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
  247. data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
  248. data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
  249. data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
  250. data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
  251. data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
  252. data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
  253. data/spec/unit/mongoid/matchers_spec.rb +329 -0
  254. data/spec/unit/mongoid/memoization_spec.rb +75 -0
  255. data/spec/unit/mongoid/named_scope_spec.rb +123 -0
  256. data/spec/unit/mongoid/paranoia_spec.rb +108 -0
  257. data/spec/unit/mongoid/paths_spec.rb +272 -0
  258. data/spec/unit/mongoid/persistence/insert_embedded_spec.rb +154 -0
  259. data/spec/unit/mongoid/persistence/insert_spec.rb +144 -0
  260. data/spec/unit/mongoid/persistence/remove_all_spec.rb +82 -0
  261. data/spec/unit/mongoid/persistence/remove_embedded_spec.rb +152 -0
  262. data/spec/unit/mongoid/persistence/remove_spec.rb +89 -0
  263. data/spec/unit/mongoid/persistence/update_spec.rb +177 -0
  264. data/spec/unit/mongoid/persistence_spec.rb +452 -0
  265. data/spec/unit/mongoid/scope_spec.rb +240 -0
  266. data/spec/unit/mongoid/serialization_spec.rb +43 -0
  267. data/spec/unit/mongoid/state_spec.rb +94 -0
  268. data/spec/unit/mongoid/timestamps_spec.rb +30 -0
  269. data/spec/unit/mongoid/validations/associated_spec.rb +103 -0
  270. data/spec/unit/mongoid/validations/uniqueness_spec.rb +201 -0
  271. data/spec/unit/mongoid/validations_spec.rb +43 -0
  272. data/spec/unit/mongoid/versioning_spec.rb +41 -0
  273. data/spec/unit/mongoid_spec.rb +46 -0
  274. metadata +433 -0
@@ -0,0 +1,89 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistence::Remove do
4
+
5
+ let(:document) do
6
+ Patient.new(:title => "Mr")
7
+ end
8
+
9
+ let(:address) do
10
+ Address.new(:street => "Oxford St")
11
+ end
12
+
13
+ let(:collection) do
14
+ stub.quacks_like(Mongoid::Collection.allocate)
15
+ end
16
+
17
+ before do
18
+ document.stubs(:collection).returns(collection)
19
+ end
20
+
21
+ describe "#initialize" do
22
+
23
+ let(:remove) do
24
+ Mongoid::Persistence::Remove.new(document)
25
+ end
26
+
27
+ it "sets the document" do
28
+ remove.document.should == document
29
+ end
30
+
31
+ it "sets the collection" do
32
+ remove.collection.should == document.collection
33
+ end
34
+
35
+ it "defaults validation to true" do
36
+ remove.validate.should == true
37
+ end
38
+
39
+ it "sets the options" do
40
+ remove.options.should ==
41
+ { :safe => Mongoid.persist_in_safe_mode }
42
+ end
43
+ end
44
+
45
+ describe "#persist" do
46
+
47
+ def root_delete_expectation
48
+ lambda {
49
+ collection.expects(:remove).with(
50
+ { :_id => document.id },
51
+ :safe => true
52
+ ).returns(true)
53
+ }
54
+ end
55
+
56
+ let(:remove) do
57
+ Mongoid::Persistence::Remove.new(document)
58
+ end
59
+
60
+ context "when the document is a root document" do
61
+
62
+ it "removes the document from the collection" do
63
+ root_delete_expectation.call
64
+ remove.persist.should == true
65
+ end
66
+ end
67
+
68
+ context "when the document is embedded" do
69
+
70
+ before do
71
+ document.addresses << address
72
+ end
73
+
74
+ let(:remove) do
75
+ Mongoid::Persistence::Remove.new(address)
76
+ end
77
+
78
+ let(:persister) do
79
+ stub.quacks_like(Mongoid::Persistence::RemoveEmbedded.allocate)
80
+ end
81
+
82
+ it "delegates to the embedded persister" do
83
+ Mongoid::Persistence::RemoveEmbedded.expects(:new).with(address, true).returns(persister)
84
+ persister.expects(:persist).returns(true)
85
+ remove.persist.should == true
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,177 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistence::Update do
4
+
5
+ let(:document) do
6
+ Patient.instantiate("_id" => BSON::ObjectID.new)
7
+ end
8
+
9
+ let(:address) do
10
+ Address.instantiate("_id" => "oxford-st", "street" => "Oxford St")
11
+ end
12
+
13
+ let(:root_category) do
14
+ RootCategory.instantiate("_id" => BSON::ObjectID.new.to_s)
15
+ end
16
+
17
+ let(:category) do
18
+ Category.instantiate("_id" => BSON::ObjectID.new.to_s, "name" => 'Programming')
19
+ end
20
+
21
+ let(:collection) do
22
+ stub.quacks_like(Mongoid::Collection.allocate)
23
+ end
24
+
25
+ before do
26
+ document.stubs(:collection).returns(collection)
27
+ root_category.stubs(:collection).returns(collection)
28
+ end
29
+
30
+ describe "#initialize" do
31
+
32
+ let(:update) do
33
+ Mongoid::Persistence::Update.new(document)
34
+ end
35
+
36
+ it "sets the document" do
37
+ update.document.should == document
38
+ end
39
+
40
+ it "sets the collection" do
41
+ update.collection.should == document.collection
42
+ end
43
+
44
+ it "defaults validation to true" do
45
+ update.validate.should == true
46
+ end
47
+ end
48
+
49
+ describe "#persist" do
50
+
51
+ def root_set_expectation
52
+ lambda {
53
+ collection.expects(:update).with(
54
+ { "_id" => document.id },
55
+ { "$set" => document.setters },
56
+ :multi => false,
57
+ :safe => true
58
+ ).returns("Object")
59
+ }
60
+ end
61
+
62
+ def embedded_set_expectation
63
+ lambda {
64
+ collection.expects(:update).with(
65
+ { "_id" => document.id, "addresses._id" => address.id },
66
+ { "$set" => address.setters },
67
+ :multi => false,
68
+ :safe => true
69
+ ).returns("Object")
70
+ }
71
+ end
72
+
73
+ def tree_set_expectation
74
+ lambda {
75
+ collection.expects(:update).with(
76
+ { "_id" => root_category.id, "categories._id" => category.id, "categories.0.categories._id" => leaf_category.id },
77
+ { "$set" => leaf_category.setters },
78
+ :multi => false,
79
+ :safe => true
80
+ ).returns("Object")
81
+ }
82
+ end
83
+
84
+ let(:update) do
85
+ Mongoid::Persistence::Update.new(document)
86
+ end
87
+
88
+ context "when the document is changed" do
89
+
90
+ before do
91
+ document.title = "Sir"
92
+ end
93
+
94
+ context "when the document is valid" do
95
+
96
+ it "performs a $set for changed fields" do
97
+ root_set_expectation.call
98
+ update.persist.should == true
99
+ end
100
+
101
+ it "moves the changed fields to previously changed" do
102
+ root_set_expectation.call
103
+ update.persist
104
+ document.changed?.should == false
105
+ end
106
+
107
+ end
108
+
109
+ context "when the document is not valid" do
110
+
111
+ before do
112
+ document.stubs(:valid?).returns(false)
113
+ end
114
+
115
+ it "returns false" do
116
+ update.persist.should == false
117
+ end
118
+ end
119
+
120
+ context "when not validating" do
121
+
122
+ before do
123
+ update.instance_variable_set(:@validate, false)
124
+ document.stubs(:valid?).returns(false)
125
+ end
126
+
127
+ after do
128
+ update.instance_variable_set(:@validate, true)
129
+ end
130
+
131
+ it "updates the document in the database" do
132
+ root_set_expectation.call
133
+ update.persist.should == true
134
+ end
135
+ end
136
+
137
+ context "when the document is embedded" do
138
+
139
+ let(:embedded) do
140
+ Mongoid::Persistence::Update.new(address)
141
+ end
142
+
143
+ before do
144
+ # TODO: What to do about composite keys?
145
+ document.addresses << address
146
+ address.city = "London"
147
+ end
148
+
149
+ it "performs a $set for the embedded changed fields" do
150
+ embedded_set_expectation.call
151
+ embedded.persist
152
+ end
153
+ end
154
+
155
+ context "when the document is a tree" do
156
+ let(:leaf_category) do
157
+ Category.instantiate("_id" => BSON::ObjectID.new, "name" => 'Ruby')
158
+ end
159
+
160
+ let(:embedded) do
161
+ Mongoid::Persistence::Update.new(leaf_category)
162
+ end
163
+
164
+ before do
165
+ category.categories << leaf_category
166
+ root_category.categories << category
167
+ leaf_category.name = 'C++'
168
+ end
169
+
170
+ it "performs a $set for the embedded changed fields" do
171
+ tree_set_expectation.call
172
+ embedded.persist
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,452 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Persistence do
4
+
5
+ let(:person) do
6
+ Person.new
7
+ end
8
+
9
+ describe ".create" do
10
+
11
+ let(:insert) do
12
+ stub.quacks_like(Mongoid::Persistence::Insert.allocate)
13
+ end
14
+
15
+ let(:patient) do
16
+ stub.quacks_like(Patient.allocate)
17
+ end
18
+
19
+ before do
20
+ Patient.expects(:new).returns(patient)
21
+ patient.expects(:insert).returns(patient)
22
+ end
23
+
24
+ it "delegates to the insert persistence command" do
25
+ Patient.create
26
+ end
27
+
28
+ it "returns the new document" do
29
+ Patient.create.should == patient
30
+ end
31
+ end
32
+
33
+ describe ".create!" do
34
+
35
+ let(:insert) do
36
+ stub.quacks_like(Mongoid::Persistence::Insert.allocate)
37
+ end
38
+
39
+ let(:patient) do
40
+ stub.quacks_like(Patient.allocate)
41
+ end
42
+
43
+ before do
44
+ Patient.expects(:new).returns(patient)
45
+ patient.expects(:insert).returns(patient)
46
+ end
47
+
48
+ context "when validation passes" do
49
+
50
+ before do
51
+ patient.expects(:errors).returns([])
52
+ end
53
+
54
+ it "returns the new document" do
55
+ Patient.create!.should == patient
56
+ end
57
+ end
58
+
59
+ context "when validation fails" do
60
+
61
+ before do
62
+ errors = stub(:any? => true, :full_messages => [ "Message" ])
63
+ patient.expects(:errors).at_least_once.returns(errors)
64
+ end
65
+
66
+ it "raises an error" do
67
+ lambda { Patient.create! }.should raise_error(Mongoid::Errors::Validations)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe ".delete_all" do
73
+
74
+ context "when conditions provided" do
75
+
76
+ let(:remove_all) do
77
+ stub.quacks_like(Mongoid::Persistence::RemoveAll.allocate)
78
+ end
79
+
80
+ before do
81
+ Mongoid::Persistence::RemoveAll.expects(:new).with(
82
+ Person, false, { :field => "value" }
83
+ ).returns(remove_all)
84
+ remove_all.expects(:persist).returns(30)
85
+ end
86
+
87
+ it "removes all documents from the collection for the conditions" do
88
+ Person.delete_all(:conditions => { :field => "value" })
89
+ end
90
+
91
+ it "returns the number of documents removed" do
92
+ Person.delete_all(:conditions => { :field => "value" }).should == 30
93
+ end
94
+ end
95
+
96
+ context "when conditions not provided" do
97
+
98
+ let(:remove_all) do
99
+ stub.quacks_like(Mongoid::Persistence::RemoveAll.allocate)
100
+ end
101
+
102
+ before do
103
+ Mongoid::Persistence::RemoveAll.expects(:new).with(Person, false, {}).returns(remove_all)
104
+ remove_all.expects(:persist).returns(30)
105
+ end
106
+
107
+ it "removes all documents from the collection" do
108
+ Person.delete_all
109
+ end
110
+
111
+ it "returns the number of documents removed" do
112
+ Person.delete_all.should == 30
113
+ end
114
+ end
115
+ end
116
+
117
+ describe ".destroy_all" do
118
+
119
+ let(:remove) do
120
+ stub.quacks_like(Mongoid::Persistence::Remove.allocate)
121
+ end
122
+
123
+ context "when conditions provided" do
124
+
125
+ before do
126
+ Person.expects(:all).with(:conditions => { :title => "Sir" }).returns([ person ])
127
+ person.expects(:run_callbacks).with(:destroy).yields
128
+ Mongoid::Persistence::Remove.expects(:new).with(person).returns(remove)
129
+ remove.expects(:persist).returns(true)
130
+ end
131
+
132
+ it "destroys each found document" do
133
+ Person.destroy_all(:conditions => { :title => "Sir" })
134
+ end
135
+
136
+ it "returns the number destroyed" do
137
+ Person.destroy_all(:conditions => { :title => "Sir" }).should == 1
138
+ end
139
+ end
140
+
141
+ context "when conditions not provided" do
142
+
143
+ before do
144
+ Person.expects(:all).with({}).returns([ person ])
145
+ person.expects(:run_callbacks).with(:destroy).yields
146
+ Mongoid::Persistence::Remove.expects(:new).with(person).returns(remove)
147
+ remove.expects(:persist).returns(true)
148
+ end
149
+
150
+ it "destroys each found document" do
151
+ Person.destroy_all
152
+ end
153
+
154
+ it "returns the number destroyed" do
155
+ Person.destroy_all.should == 1
156
+ end
157
+ end
158
+ end
159
+
160
+ describe "#delete" do
161
+
162
+ let(:remove) do
163
+ stub.quacks_like(Mongoid::Persistence::Remove.allocate)
164
+ end
165
+
166
+ before do
167
+ Mongoid::Persistence::Remove.expects(:new).with(person).returns(remove)
168
+ end
169
+
170
+ it "delegates to the remove persistence command" do
171
+ remove.expects(:persist).returns(true)
172
+ person.delete.should == true
173
+ end
174
+ end
175
+
176
+ describe "#destroy" do
177
+
178
+ let(:remove) do
179
+ stub.quacks_like(Mongoid::Persistence::Remove.allocate)
180
+ end
181
+
182
+ before do
183
+ Mongoid::Persistence::Remove.expects(:new).with(person).returns(remove)
184
+ end
185
+
186
+ it "delegates to the remove persistence command" do
187
+ person.expects(:run_callbacks).with(:destroy).yields.returns(true)
188
+ remove.expects(:persist).returns(true)
189
+ person.destroy.should == true
190
+ end
191
+ end
192
+
193
+ describe "#insert" do
194
+
195
+ let(:insert) do
196
+ stub.quacks_like(Mongoid::Persistence::Insert.allocate)
197
+ end
198
+
199
+ before do
200
+ Mongoid::Persistence::Insert.expects(:new).with(person, true).returns(insert)
201
+ end
202
+
203
+ it "delegates to the insert persistence command" do
204
+ insert.expects(:persist).returns(person)
205
+ person.insert.should == person
206
+ end
207
+ end
208
+
209
+ describe "#_remove" do
210
+
211
+ let(:remove) do
212
+ stub.quacks_like(Mongoid::Persistence::Remove.allocate)
213
+ end
214
+
215
+ before do
216
+ Mongoid::Persistence::Remove.expects(:new).with(person).returns(remove)
217
+ end
218
+
219
+ it "delegates to the remove persistence command" do
220
+ remove.expects(:persist).returns(true)
221
+ person._remove.should == true
222
+ end
223
+ end
224
+
225
+ describe "#save" do
226
+
227
+ context "when the document is new" do
228
+
229
+ let(:insert) do
230
+ stub.quacks_like(Mongoid::Persistence::Insert.allocate)
231
+ end
232
+
233
+ before do
234
+ Mongoid::Persistence::Insert.expects(:new).with(person, true).returns(insert)
235
+ end
236
+
237
+ it "delegates to the insert persistence command" do
238
+ insert.expects(:persist).returns(person)
239
+ person.save
240
+ end
241
+
242
+ it "returns a boolean" do
243
+ person.expects(:persisted?).returns(true)
244
+ insert.expects(:persist).returns(person)
245
+ person.save.should == true
246
+ end
247
+ end
248
+
249
+ context "when the document is not new" do
250
+
251
+ let(:update) do
252
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
253
+ end
254
+
255
+ before do
256
+ person.instance_variable_set(:@new_record, false)
257
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
258
+ end
259
+
260
+ it "delegates to the update persistence command" do
261
+ update.expects(:persist).returns(true)
262
+ person.save
263
+ end
264
+
265
+ it "returns a boolean" do
266
+ update.expects(:persist).returns(true)
267
+ person.save.should == true
268
+ end
269
+ end
270
+ end
271
+
272
+ describe "#save!" do
273
+
274
+ context "when validation passes" do
275
+
276
+ let(:update) do
277
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
278
+ end
279
+
280
+ before do
281
+ person.instance_variable_set(:@new_record, false)
282
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
283
+ update.expects(:persist).returns(true)
284
+ end
285
+
286
+ it "returns true" do
287
+ person.save!.should == true
288
+ end
289
+ end
290
+
291
+ context "when validation failes" do
292
+
293
+ let(:update) do
294
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
295
+ end
296
+
297
+ before do
298
+ person.instance_variable_set(:@new_record, false)
299
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
300
+ update.expects(:persist).returns(false)
301
+ end
302
+
303
+ it "raises an error" do
304
+ lambda { person.save! }.should raise_error(Mongoid::Errors::Validations)
305
+ end
306
+ end
307
+ end
308
+
309
+ describe "#update" do
310
+
311
+ let(:update) do
312
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
313
+ end
314
+
315
+ before do
316
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
317
+ end
318
+
319
+ it "delegates to the update persistence command" do
320
+ update.expects(:persist).returns(true)
321
+ person.update.should == true
322
+ end
323
+ end
324
+
325
+ describe "#update_attributes" do
326
+
327
+ let(:update) do
328
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
329
+ end
330
+
331
+ before do
332
+ person.instance_variable_set(:@new_record, false)
333
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
334
+ end
335
+
336
+ it "writes attributes and performs an update" do
337
+ update.expects(:persist).returns(true)
338
+ person.update_attributes(:title => "Mam")
339
+ person.title.should == "Mam"
340
+ end
341
+ end
342
+
343
+ describe "#update_attributes!" do
344
+
345
+ let(:update) do
346
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
347
+ end
348
+
349
+ before do
350
+ person.instance_variable_set(:@new_record, false)
351
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
352
+ end
353
+
354
+ context "when validation passes" do
355
+
356
+ it "writes attributes and performs an update" do
357
+ update.expects(:persist).returns(true)
358
+ person.update_attributes!(:title => "Mam").should be_true
359
+ person.title.should == "Mam"
360
+ end
361
+ end
362
+
363
+ context "when validation fails" do
364
+
365
+ it "raises an error" do
366
+ update.expects(:persist).returns(false)
367
+ lambda {
368
+ person.update_attributes!(:title => "Mam")
369
+ }.should raise_error(Mongoid::Errors::Validations)
370
+ end
371
+ end
372
+ end
373
+
374
+ describe "#upsert" do
375
+
376
+ context "when passing a hash as a validation parameter" do
377
+
378
+ let(:insert) do
379
+ stub.quacks_like(Mongoid::Persistence::Insert.allocate)
380
+ end
381
+
382
+ before do
383
+ Mongoid::Persistence::Insert.expects(:new).with(person, false).returns(insert)
384
+ end
385
+
386
+ it "delegates to the insert persistence command" do
387
+ insert.expects(:persist).returns(person)
388
+ person.upsert(:validate => false)
389
+ end
390
+ end
391
+
392
+ context "when the document is new" do
393
+
394
+ let(:insert) do
395
+ stub.quacks_like(Mongoid::Persistence::Insert.allocate)
396
+ end
397
+
398
+ context "when validation passes" do
399
+
400
+ before do
401
+ Mongoid::Persistence::Insert.expects(:new).with(person, true).returns(insert)
402
+ end
403
+
404
+ it "delegates to the insert persistence command" do
405
+ person.expects(:persisted?).returns(true)
406
+ insert.expects(:persist).returns(person)
407
+ person.upsert
408
+ end
409
+
410
+ it "returns a boolean" do
411
+ person.expects(:persisted?).returns(true)
412
+ insert.expects(:persist).returns(person)
413
+ person.upsert.should == true
414
+ end
415
+ end
416
+
417
+ context "when validation fails" do
418
+
419
+ before do
420
+ Mongoid::Persistence::Insert.expects(:new).with(person, true).returns(insert)
421
+ end
422
+
423
+ it "returns false" do
424
+ insert.expects(:persist).returns(person)
425
+ person.upsert.should == false
426
+ end
427
+ end
428
+ end
429
+
430
+ context "when the document is not new" do
431
+
432
+ let(:update) do
433
+ stub.quacks_like(Mongoid::Persistence::Update.allocate)
434
+ end
435
+
436
+ before do
437
+ person.instance_variable_set(:@new_record, false)
438
+ Mongoid::Persistence::Update.expects(:new).with(person, true).returns(update)
439
+ end
440
+
441
+ it "delegates to the update persistence command" do
442
+ update.expects(:persist).returns(true)
443
+ person.upsert
444
+ end
445
+
446
+ it "returns a boolean" do
447
+ update.expects(:persist).returns(true)
448
+ person.upsert.should == true
449
+ end
450
+ end
451
+ end
452
+ end