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,741 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Document do
4
+
5
+ before do
6
+ Person.delete_all
7
+ end
8
+
9
+ context "creating anonymous documents" do
10
+
11
+ context "when defining collection" do
12
+
13
+ before do
14
+ @model = Class.new do
15
+ include Mongoid::Document
16
+ store_in :anonymous
17
+ field :gender
18
+ end
19
+ end
20
+
21
+ it "allows the creation" do
22
+ Object.const_set "Anonymous", @model
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "#db" do
28
+
29
+ it "returns the mongo database" do
30
+ Person.db.should == Mongoid.master
31
+ end
32
+ end
33
+
34
+ context "when document contains a hash field" do
35
+
36
+ before do
37
+ @map = { "first" => 10, "second" => "Blah" }
38
+ @person = Person.create(:map => @map)
39
+ end
40
+
41
+ it "properly gets and sets the has attributes" do
42
+ @person.map.should == @map
43
+ @from_db = Person.find(@person.id)
44
+ @from_db.map.should == @map
45
+ end
46
+
47
+ end
48
+
49
+ describe ".collection" do
50
+
51
+ context "on a subclass of a root document" do
52
+
53
+ it "returns the root document collection" do
54
+ Browser.collection.should == Canvas.collection
55
+ end
56
+
57
+ end
58
+
59
+ context "on a namespaced document" do
60
+ Medical::Patient.collection.name.should == "medical_patients"
61
+ end
62
+
63
+ end
64
+
65
+ describe "#new" do
66
+
67
+ it "gets a new or current database connection" do
68
+ person = Person.new
69
+ person.collection.should be_a_kind_of(Mongoid::Collection)
70
+ end
71
+
72
+ end
73
+
74
+ describe "#count" do
75
+
76
+ before do
77
+ 5.times do |n|
78
+ Person.create(:title => "Sir", :ssn => "#{n}")
79
+ end
80
+ end
81
+
82
+ it "returns the count" do
83
+ Person.count.should == 5
84
+ end
85
+
86
+ end
87
+
88
+ describe "#create" do
89
+
90
+ it "persists a new record to the database" do
91
+ person = Person.create(:title => "Test")
92
+ person.id.should be_a_kind_of(String)
93
+ person.attributes[:title].should == "Test"
94
+ end
95
+
96
+ context "when creating a has many" do
97
+
98
+ before do
99
+ @person = Person.new(:title => "Esquire")
100
+ @person.addresses.create(:street => "Nan Jing Dong Lu", :city => "Shanghai")
101
+ end
102
+
103
+ it "should create and save the entire graph" do
104
+ person = Person.find(@person.id)
105
+ person.addresses.first.street.should == "Nan Jing Dong Lu"
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+
112
+ context "chaining criteria scopes" do
113
+
114
+ before do
115
+ @one = Person.create(:title => "Mr", :age => 55, :terms => true, :ssn => "q")
116
+ @two = Person.create(:title => "Sir", :age => 55, :terms => true, :ssn => "w")
117
+ @three = Person.create(:title => "Sir", :age => 35, :terms => true, :ssn => "e")
118
+ @four = Person.create(:title => "Sir", :age => 55, :terms => false, :ssn => "r")
119
+ end
120
+
121
+ it "finds by the merged criteria" do
122
+ people = Person.old.accepted.knight
123
+ people.count.should == 1
124
+ people.first.should == @two
125
+ end
126
+
127
+ end
128
+
129
+ context "#destroy" do
130
+
131
+ context "on a root document" do
132
+
133
+ before do
134
+ @person = Person.create(:title => "Sir")
135
+ end
136
+
137
+ it "deletes the document" do
138
+ @person.destroy
139
+ lambda { Person.find(@person.id) }.should raise_error
140
+ end
141
+
142
+ it "marks the document as destroyed" do
143
+ @person.should_not be_destroyed
144
+ @person.destroy
145
+ @person.should be_destroyed
146
+ end
147
+
148
+ end
149
+
150
+ context "on an embedded document" do
151
+
152
+ before do
153
+ @person = Person.create(:title => "Lead")
154
+ address = @person.addresses.create(:street => "1st Street")
155
+ @person.create_name(:first_name => "Emmanuel")
156
+ @person.save
157
+ end
158
+
159
+ it "deletes the document" do
160
+ @person.addresses.first.destroy
161
+ @person.name.should_not be_nil
162
+ @person.name.destroy
163
+ @person.addresses.first.should be_nil
164
+ @person.name.should be_nil
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+
171
+ context ".find_or_create_by" do
172
+
173
+ before do
174
+ @person = Person.create(:title => "Senior")
175
+ end
176
+
177
+ context "when the document is found" do
178
+
179
+ it "returns the document" do
180
+ Person.find_or_create_by(:title => "Senior").should == @person
181
+ end
182
+
183
+ end
184
+
185
+ context "when the document is not found" do
186
+
187
+ it "creates a new document" do
188
+ person = Person.find_or_create_by(:title => "Senorita", :ssn => "1234567")
189
+ person.title.should == "Senorita"
190
+ person.should_not be_a_new_record
191
+ end
192
+
193
+ end
194
+
195
+ end
196
+
197
+ context ".find_or_initialize_by" do
198
+
199
+ before do
200
+ @person = Person.create(:title => "Senior")
201
+ end
202
+
203
+ context "when the document is found" do
204
+
205
+ it "returns the document" do
206
+ Person.find_or_initialize_by(:title => "Senior").should == @person
207
+ end
208
+
209
+ end
210
+
211
+ context "when the document is not found" do
212
+
213
+ it "returns a new document" do
214
+ person = Person.find_or_initialize_by(:title => "Senorita")
215
+ person.title.should == "Senorita"
216
+ person.should be_a_new_record
217
+ end
218
+
219
+ end
220
+
221
+ end
222
+
223
+ describe "#find" do
224
+
225
+ before do
226
+ @person = Person.create(:title => "Test")
227
+ end
228
+
229
+ context "finding all documents" do
230
+
231
+ it "returns an array of documents based on the selector provided" do
232
+ documents = Person.find(:all, :conditions => { :title => "Test"})
233
+ documents.first.title.should == "Test"
234
+ end
235
+
236
+ end
237
+
238
+ context "finding first document" do
239
+
240
+ it "returns the first document based on the selector provided" do
241
+ person = Person.find(:first, :conditions => { :title => "Test" })
242
+ person.title.should == "Test"
243
+ end
244
+
245
+ end
246
+
247
+ context "finding by id" do
248
+
249
+ it "finds the document by the supplied id" do
250
+ person = Person.find(@person.id)
251
+ person.id.should == @person.id
252
+ end
253
+
254
+ end
255
+
256
+ context "limiting result fields" do
257
+
258
+ it "adds the type field to the options" do
259
+ people = Person.all(:fields => [ :title ])
260
+ people.first.title.should == "Test"
261
+ end
262
+
263
+ end
264
+
265
+ end
266
+
267
+ describe "#group" do
268
+
269
+ before do
270
+ 5.times do |num|
271
+ Person.create(:title => "Sir", :age => num, :ssn => num)
272
+ end
273
+ end
274
+
275
+ it "returns grouped documents" do
276
+ grouped = Person.only(:title).group
277
+ people = grouped.first["group"]
278
+ person = people.first
279
+ person.should be_a_kind_of(Person)
280
+ person.title.should == "Sir"
281
+ end
282
+
283
+ end
284
+
285
+ context "when address is a has one" do
286
+
287
+ before do
288
+ @owner = PetOwner.create(:title => "AKC")
289
+ @address = Address.new(:street => "Fido Street")
290
+ @owner.address = @address
291
+ @address.save
292
+ end
293
+
294
+ after do
295
+ PetOwner.delete_all
296
+ end
297
+
298
+ it "is a single object and not an array" do
299
+ @from_db = PetOwner.find(@owner.id)
300
+ @from_db.address.should == @address
301
+ end
302
+
303
+ end
304
+
305
+ describe "#inspect" do
306
+
307
+ context "with allow_dynamic_fields = false" do
308
+ before do
309
+ Mongoid.configure.allow_dynamic_fields = false
310
+ @person = Person.new :title => "CEO"
311
+ end
312
+
313
+ it "returns a pretty string of class name and attributes" do
314
+ attrs = Person.fields.map do |name, field|
315
+ "#{name}: #{@person.attributes[name].nil? ? "nil" : @person.attributes[name].inspect}"
316
+ end * ", "
317
+ @person.inspect.should == "#<Person _id: #{@person.id}, #{attrs}>"
318
+ end
319
+ end
320
+
321
+ context "with allow_dynamic_fields = true" do
322
+ before do
323
+ Mongoid.configure.allow_dynamic_fields = true
324
+ @person = Person.new(:title => "CEO", :some_attribute => "foo")
325
+ @person.addresses << Address.new(:street => "test")
326
+ end
327
+
328
+ it "returns a pretty string of class name, attributes, and dynamic attributes" do
329
+ attrs = Person.fields.map do |name, field|
330
+ "#{name}: #{@person.attributes[name].nil? ? "nil" : @person.attributes[name].inspect}"
331
+ end * ", "
332
+ attrs << ", some_attribute: #{@person.attributes['some_attribute'].inspect}"
333
+ @person.inspect.should == "#<Person _id: #{@person.id}, #{attrs}>"
334
+ end
335
+ end
336
+ end
337
+
338
+ describe "#paginate" do
339
+
340
+ before do
341
+ 10.times do |num|
342
+ Person.create(:title => "Test-#{num}", :ssn => "55#{num}")
343
+ end
344
+ end
345
+
346
+ it "returns paginated documents" do
347
+ Person.paginate(:per_page => 5, :page => 2).length.should == 5
348
+ end
349
+
350
+ it "returns a proper count" do
351
+ @criteria = Mongoid::Criteria.translate(Person, { :per_page => 5, :page => 1 })
352
+ @criteria.count.should == 10
353
+ end
354
+
355
+ end
356
+
357
+ describe "#reload" do
358
+
359
+ before do
360
+ @person = Person.new(:title => "Sir")
361
+ @person.save
362
+ @from_db = Person.find(@person.id)
363
+ @from_db.age = 35
364
+ @from_db.save
365
+ end
366
+
367
+ it "reloads the object attributes from the db" do
368
+ @person.reload
369
+ @person.age.should == 35
370
+ end
371
+
372
+ it "reload should return self" do
373
+ @person.reload.should == @from_db
374
+ end
375
+
376
+ context "when document not saved" do
377
+
378
+ context "when raising not found error" do
379
+
380
+ it "raises an error" do
381
+ lambda { Person.new.reload }.should raise_error(Mongoid::Errors::DocumentNotFound)
382
+ end
383
+ end
384
+ end
385
+
386
+ context "when embedded documents change" do
387
+
388
+ before do
389
+ @address = @person.addresses.create(:number => 27, :street => "Maiden Lane")
390
+ end
391
+
392
+ it "should reload (unmemoize) the associations" do
393
+ @person.addresses.should == [ @address ]
394
+ Person.collection.update({ "_id" => @person.id }, { "$set" => { "addresses" => [] } })
395
+ @person.reload
396
+ @person.addresses.should == []
397
+ end
398
+ end
399
+
400
+ context "with relational associations" do
401
+
402
+ context "for a references_one" do
403
+
404
+ before do
405
+ @game = @person.game.create(:score => 50)
406
+ end
407
+
408
+ it "should reload the association" do
409
+ @person.game.should == @game
410
+ Game.collection.update({ "_id" => @game.id }, { "$set" => { "score" => 75 } })
411
+ @person.reload
412
+ @person.game.score.should == 75
413
+ end
414
+ end
415
+
416
+ context "for a referenced_in" do
417
+
418
+ before do
419
+ @game = @person.game.create(:score => 50)
420
+ end
421
+
422
+ it "should reload the association" do
423
+ Person.collection.update({ "_id" => @person.id }, { "$set" => { "title" => "Mam" } })
424
+ @game.reload
425
+ @game.person.title.should == "Mam"
426
+ end
427
+ end
428
+ end
429
+ end
430
+
431
+ describe "#save" do
432
+
433
+ context "on a has_one association" do
434
+
435
+ before do
436
+ @person = Person.new(:title => "Sir")
437
+ @name = Name.new(:first_name => "Test")
438
+ @person.name = @name
439
+ end
440
+
441
+ it "saves the parent document" do
442
+ @name.save
443
+ person = Person.find(@person.id)
444
+ person.name.first_name.should == @name.first_name
445
+ end
446
+
447
+ end
448
+
449
+ context "without validation" do
450
+
451
+ before do
452
+ @comment = Comment.new
453
+ end
454
+
455
+ it "always persists" do
456
+ @comment.save(false).should be_true
457
+ @from_db = Comment.find(@comment.id)
458
+ @from_db.should == @comment
459
+ end
460
+
461
+ end
462
+
463
+ context "with failing validation" do
464
+
465
+ before do
466
+ @comment = Comment.new
467
+ end
468
+
469
+ it "returns false" do
470
+ @comment.should_not be_valid
471
+ end
472
+
473
+ end
474
+
475
+ end
476
+
477
+ context ".store_in" do
478
+
479
+ after do
480
+ Canvas.store_in(:canvases)
481
+ end
482
+
483
+ it "switches the database collection" do
484
+ Canvas.collection.name.should == "canvases"
485
+ Canvas.store_in(:browsers)
486
+ Canvas.collection.name.should == "browsers"
487
+ end
488
+
489
+ end
490
+
491
+ context "when has many exists through a has one" do
492
+
493
+ before do
494
+ @owner = PetOwner.new(:title => "Sir")
495
+ @pet = Pet.new(:name => "Fido")
496
+ @visit = VetVisit.new(:date => Date.today)
497
+ @pet.vet_visits << @visit
498
+ @owner.pet = @pet
499
+ end
500
+
501
+ it "can clear the association" do
502
+ @owner.pet.vet_visits.size.should == 1
503
+ @owner.pet.vet_visits.clear
504
+ @owner.pet.vet_visits.size.should == 0
505
+ end
506
+
507
+ end
508
+
509
+ context "the lot" do
510
+
511
+ before do
512
+ @person = Person.new(:title => "Sir")
513
+ @name = Name.new(:first_name => "Syd", :last_name => "Vicious")
514
+ @home = Address.new(:street => "Oxford Street")
515
+ @business = Address.new(:street => "Upper Street")
516
+ @person.name = @name
517
+ @person.addresses << @home
518
+ @person.addresses << @business
519
+ end
520
+
521
+ it "allows adding multiples on an embeds_many in a row" do
522
+ @person.addresses.length.should == 2
523
+ end
524
+
525
+ context "when saving on a has_one" do
526
+
527
+ before do
528
+ @name.save
529
+ end
530
+
531
+ it "saves the entire graph up from the has_one" do
532
+ person = Person.first(:conditions => { :title => "Sir" })
533
+ person.should == @person
534
+ end
535
+
536
+ end
537
+
538
+ context "when saving on an embeds_many" do
539
+
540
+ before do
541
+ @home.save
542
+ end
543
+
544
+ it "saves the entire graph up from the embeds_many" do
545
+ person = Person.first(:conditions => { :title => "Sir" })
546
+ person.should == @person
547
+ end
548
+ end
549
+
550
+ end
551
+
552
+ context "setting embedded_in" do
553
+
554
+ before do
555
+ @person = Person.new(:title => "Mr")
556
+ @address = Address.new(:street => "Bloomsbury Ave")
557
+ @person.save!
558
+ end
559
+
560
+ it "allows the parent reference to change" do
561
+ @address.addressable = @person
562
+ @address.save!
563
+ @person.addresses.first.should == @address
564
+ end
565
+
566
+ end
567
+
568
+ describe "#to_json" do
569
+
570
+ before do
571
+ @person = Person.new(:title => "Sir", :age => 30)
572
+ @address = Address.new(:street => "Nan Jing Dong Lu")
573
+ @person.addresses << @address
574
+ end
575
+
576
+ context "on a new document" do
577
+
578
+ it "returns the json string" do
579
+ @person.to_json.should include('"pets":false')
580
+ end
581
+
582
+ end
583
+
584
+ context "on a persisted document" do
585
+
586
+ it "returns the json string" do
587
+ @person.save
588
+ from_db = Person.find(@person.id)
589
+ from_db.to_json.should include('"pets":false')
590
+ end
591
+
592
+ end
593
+
594
+ end
595
+
596
+ describe "#as_json" do
597
+
598
+ before do
599
+ @person = Person.new(:title => "Sir", :age => 30)
600
+ @address = Address.new(:street => "Nan Jing Dong Lu")
601
+ @person.addresses << @address
602
+ end
603
+
604
+ context "on a new document" do
605
+
606
+ it "returns the document (not sure why ActiveModel behaves like this)" do
607
+ @person.as_json.should == @person
608
+ end
609
+
610
+ end
611
+
612
+ context "on a persisted document" do
613
+
614
+ it "returns the attributes" do
615
+ @person.save
616
+ from_db = Person.find(@person.id)
617
+ from_db.as_json.should == from_db
618
+ end
619
+
620
+ end
621
+
622
+ end
623
+
624
+ describe "#encode_json" do
625
+
626
+ before do
627
+ @person = Person.new(:title => "Sir", :age => 30)
628
+ @address = Address.new(:street => "Nan Jing Dong Lu")
629
+ @person.addresses << @address
630
+ @encoder = stub(:options => {})
631
+ end
632
+
633
+ context "on a new document" do
634
+
635
+ it "returns the attributes" do
636
+ @person.encode_json(@encoder).should include('"pets":false')
637
+ end
638
+
639
+ end
640
+
641
+ context "on a persisted document" do
642
+
643
+ it "returns the attributes" do
644
+ @person.save
645
+ from_db = Person.find(@person.id)
646
+ from_db.encode_json(@encoder).should include('"pets":false')
647
+ end
648
+
649
+ end
650
+
651
+ end
652
+
653
+ context "typecasting" do
654
+
655
+ before do
656
+ @date = Date.new(1976, 7, 4)
657
+ @person = Person.new(:dob => @date)
658
+ @person.save
659
+ end
660
+
661
+ it "properly casts dates and times" do
662
+ person = Person.first
663
+ person.dob.should == @date
664
+ end
665
+
666
+ end
667
+
668
+ context "versioning" do
669
+
670
+ before do
671
+ @comment = Comment.new(:title => 'Old', :text => "Testing")
672
+ @comment.save
673
+ end
674
+
675
+ after do
676
+ Comment.collection.drop
677
+ end
678
+
679
+ context "first save" do
680
+
681
+ it "creates a new version" do
682
+ @from_db = Comment.find(@comment.id)
683
+ @from_db.title = "New"
684
+ @from_db.save
685
+ @from_db.versions.size.should == 1
686
+ @from_db.version.should == 2
687
+ end
688
+
689
+ end
690
+
691
+ context "multiple saves" do
692
+
693
+ before do
694
+ 5.times do |n|
695
+ @comment.save
696
+ end
697
+ end
698
+
699
+ it "creates new versions" do
700
+ @from_db = Comment.find(@comment.id)
701
+ @from_db.version.should == 6
702
+ @from_db.versions.size.should == 5
703
+ end
704
+
705
+ end
706
+
707
+ end
708
+
709
+ context "executing criteria with date comparisons" do
710
+
711
+ context "handling specific dates" do
712
+
713
+ before do
714
+ @person = Person.create(:dob => Date.new(2000, 10, 31))
715
+ end
716
+
717
+ it "handles comparisons with todays date"do
718
+ people = Person.where("this.dob < new Date()")
719
+ people.first.should == @person
720
+ end
721
+
722
+ it "handles conparisons with a date range" do
723
+ people = Person.where("new Date(1976, 10, 31) < this.dob && this.dob < new Date()")
724
+ people.first.should == @person
725
+ end
726
+
727
+ it "handles false comparisons in a date range" do
728
+ people = Person.where("new Date(2005, 10, 31) < this.dob && this.dob < new Date()")
729
+ people.should be_empty
730
+ end
731
+
732
+ it "handles comparisons with date objects"do
733
+ people = Person.where(:dob => { "$lt" => Date.today.midnight })
734
+ people.first.should == @person
735
+ end
736
+
737
+ end
738
+
739
+ end
740
+
741
+ end