mongoid_rails4 4.0.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.
Files changed (659) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3213 -0
  3. data/LICENSE +20 -0
  4. data/README.md +62 -0
  5. data/Rakefile +35 -0
  6. data/lib/config/locales/en.yml +448 -0
  7. data/lib/mongoid.rb +104 -0
  8. data/lib/mongoid/atomic.rb +384 -0
  9. data/lib/mongoid/atomic/modifiers.rb +317 -0
  10. data/lib/mongoid/atomic/paths.rb +3 -0
  11. data/lib/mongoid/atomic/paths/embedded.rb +28 -0
  12. data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
  13. data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
  14. data/lib/mongoid/atomic/paths/root.rb +39 -0
  15. data/lib/mongoid/attributes.rb +284 -0
  16. data/lib/mongoid/attributes/dynamic.rb +154 -0
  17. data/lib/mongoid/attributes/nested.rb +82 -0
  18. data/lib/mongoid/attributes/processing.rb +147 -0
  19. data/lib/mongoid/attributes/readonly.rb +56 -0
  20. data/lib/mongoid/changeable.rb +379 -0
  21. data/lib/mongoid/composable.rb +104 -0
  22. data/lib/mongoid/config.rb +263 -0
  23. data/lib/mongoid/config/environment.rb +44 -0
  24. data/lib/mongoid/config/options.rb +74 -0
  25. data/lib/mongoid/config/validators.rb +3 -0
  26. data/lib/mongoid/config/validators/option.rb +25 -0
  27. data/lib/mongoid/config/validators/session.rb +140 -0
  28. data/lib/mongoid/contextual.rb +54 -0
  29. data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
  30. data/lib/mongoid/contextual/aggregable/mongo.rb +147 -0
  31. data/lib/mongoid/contextual/atomic.rb +180 -0
  32. data/lib/mongoid/contextual/command.rb +61 -0
  33. data/lib/mongoid/contextual/eager.rb +158 -0
  34. data/lib/mongoid/contextual/find_and_modify.rb +69 -0
  35. data/lib/mongoid/contextual/geo_near.rb +238 -0
  36. data/lib/mongoid/contextual/map_reduce.rb +324 -0
  37. data/lib/mongoid/contextual/memory.rb +440 -0
  38. data/lib/mongoid/contextual/mongo.rb +676 -0
  39. data/lib/mongoid/contextual/queryable.rb +25 -0
  40. data/lib/mongoid/contextual/text_search.rb +180 -0
  41. data/lib/mongoid/copyable.rb +67 -0
  42. data/lib/mongoid/criteria.rb +562 -0
  43. data/lib/mongoid/criteria/findable.rb +179 -0
  44. data/lib/mongoid/criteria/inspectable.rb +25 -0
  45. data/lib/mongoid/criteria/marshalable.rb +50 -0
  46. data/lib/mongoid/criteria/modifiable.rb +189 -0
  47. data/lib/mongoid/criteria/scopable.rb +158 -0
  48. data/lib/mongoid/document.rb +361 -0
  49. data/lib/mongoid/equality.rb +66 -0
  50. data/lib/mongoid/errors.rb +40 -0
  51. data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
  52. data/lib/mongoid/errors/callback.rb +25 -0
  53. data/lib/mongoid/errors/delete_restriction.rb +29 -0
  54. data/lib/mongoid/errors/document_not_found.rb +111 -0
  55. data/lib/mongoid/errors/eager_load.rb +22 -0
  56. data/lib/mongoid/errors/invalid_collection.rb +18 -0
  57. data/lib/mongoid/errors/invalid_config_option.rb +27 -0
  58. data/lib/mongoid/errors/invalid_field.rb +64 -0
  59. data/lib/mongoid/errors/invalid_field_option.rb +35 -0
  60. data/lib/mongoid/errors/invalid_find.rb +19 -0
  61. data/lib/mongoid/errors/invalid_includes.rb +32 -0
  62. data/lib/mongoid/errors/invalid_index.rb +28 -0
  63. data/lib/mongoid/errors/invalid_options.rb +28 -0
  64. data/lib/mongoid/errors/invalid_path.rb +21 -0
  65. data/lib/mongoid/errors/invalid_scope.rb +24 -0
  66. data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
  67. data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
  68. data/lib/mongoid/errors/invalid_time.rb +22 -0
  69. data/lib/mongoid/errors/inverse_not_found.rb +29 -0
  70. data/lib/mongoid/errors/mixed_relations.rb +32 -0
  71. data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
  72. data/lib/mongoid/errors/mongoid_error.rb +92 -0
  73. data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
  74. data/lib/mongoid/errors/no_default_session.rb +23 -0
  75. data/lib/mongoid/errors/no_environment.rb +19 -0
  76. data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
  77. data/lib/mongoid/errors/no_metadata.rb +21 -0
  78. data/lib/mongoid/errors/no_parent.rb +24 -0
  79. data/lib/mongoid/errors/no_session_config.rb +22 -0
  80. data/lib/mongoid/errors/no_session_database.rb +27 -0
  81. data/lib/mongoid/errors/no_session_hosts.rb +27 -0
  82. data/lib/mongoid/errors/no_sessions_config.rb +20 -0
  83. data/lib/mongoid/errors/readonly_attribute.rb +25 -0
  84. data/lib/mongoid/errors/scope_overwrite.rb +21 -0
  85. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
  86. data/lib/mongoid/errors/unknown_attribute.rb +25 -0
  87. data/lib/mongoid/errors/unsaved_document.rb +19 -0
  88. data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
  89. data/lib/mongoid/errors/validations.rb +29 -0
  90. data/lib/mongoid/evolvable.rb +19 -0
  91. data/lib/mongoid/extensions.rb +35 -0
  92. data/lib/mongoid/extensions/array.rb +180 -0
  93. data/lib/mongoid/extensions/big_decimal.rb +69 -0
  94. data/lib/mongoid/extensions/boolean.rb +21 -0
  95. data/lib/mongoid/extensions/date.rb +77 -0
  96. data/lib/mongoid/extensions/date_time.rb +73 -0
  97. data/lib/mongoid/extensions/false_class.rb +38 -0
  98. data/lib/mongoid/extensions/float.rb +56 -0
  99. data/lib/mongoid/extensions/hash.rb +209 -0
  100. data/lib/mongoid/extensions/integer.rb +67 -0
  101. data/lib/mongoid/extensions/module.rb +28 -0
  102. data/lib/mongoid/extensions/nil_class.rb +33 -0
  103. data/lib/mongoid/extensions/object.rb +274 -0
  104. data/lib/mongoid/extensions/object_id.rb +54 -0
  105. data/lib/mongoid/extensions/range.rb +79 -0
  106. data/lib/mongoid/extensions/regexp.rb +27 -0
  107. data/lib/mongoid/extensions/set.rb +55 -0
  108. data/lib/mongoid/extensions/string.rb +199 -0
  109. data/lib/mongoid/extensions/symbol.rb +54 -0
  110. data/lib/mongoid/extensions/time.rb +88 -0
  111. data/lib/mongoid/extensions/time_with_zone.rb +56 -0
  112. data/lib/mongoid/extensions/true_class.rb +38 -0
  113. data/lib/mongoid/factory.rb +46 -0
  114. data/lib/mongoid/fields.rb +542 -0
  115. data/lib/mongoid/fields/foreign_key.rb +174 -0
  116. data/lib/mongoid/fields/localized.rb +73 -0
  117. data/lib/mongoid/fields/standard.rb +273 -0
  118. data/lib/mongoid/fields/validators.rb +2 -0
  119. data/lib/mongoid/fields/validators/macro.rb +92 -0
  120. data/lib/mongoid/findable.rb +133 -0
  121. data/lib/mongoid/identity_map.rb +163 -0
  122. data/lib/mongoid/indexable.rb +147 -0
  123. data/lib/mongoid/indexable/specification.rb +115 -0
  124. data/lib/mongoid/indexable/validators/options.rb +103 -0
  125. data/lib/mongoid/inspectable.rb +59 -0
  126. data/lib/mongoid/interceptable.rb +265 -0
  127. data/lib/mongoid/loggable.rb +69 -0
  128. data/lib/mongoid/matchable.rb +152 -0
  129. data/lib/mongoid/matchable/all.rb +27 -0
  130. data/lib/mongoid/matchable/and.rb +30 -0
  131. data/lib/mongoid/matchable/default.rb +72 -0
  132. data/lib/mongoid/matchable/exists.rb +23 -0
  133. data/lib/mongoid/matchable/gt.rb +21 -0
  134. data/lib/mongoid/matchable/gte.rb +21 -0
  135. data/lib/mongoid/matchable/in.rb +24 -0
  136. data/lib/mongoid/matchable/lt.rb +21 -0
  137. data/lib/mongoid/matchable/lte.rb +21 -0
  138. data/lib/mongoid/matchable/ne.rb +21 -0
  139. data/lib/mongoid/matchable/nin.rb +21 -0
  140. data/lib/mongoid/matchable/or.rb +33 -0
  141. data/lib/mongoid/matchable/size.rb +21 -0
  142. data/lib/mongoid/persistable.rb +207 -0
  143. data/lib/mongoid/persistable/creatable.rb +189 -0
  144. data/lib/mongoid/persistable/deletable.rb +149 -0
  145. data/lib/mongoid/persistable/destroyable.rb +55 -0
  146. data/lib/mongoid/persistable/incrementable.rb +36 -0
  147. data/lib/mongoid/persistable/logical.rb +38 -0
  148. data/lib/mongoid/persistable/poppable.rb +39 -0
  149. data/lib/mongoid/persistable/pullable.rb +55 -0
  150. data/lib/mongoid/persistable/pushable.rb +62 -0
  151. data/lib/mongoid/persistable/renamable.rb +35 -0
  152. data/lib/mongoid/persistable/savable.rb +52 -0
  153. data/lib/mongoid/persistable/settable.rb +33 -0
  154. data/lib/mongoid/persistable/unsettable.rb +36 -0
  155. data/lib/mongoid/persistable/updatable.rb +151 -0
  156. data/lib/mongoid/persistable/upsertable.rb +55 -0
  157. data/lib/mongoid/positional.rb +71 -0
  158. data/lib/mongoid/railtie.rb +156 -0
  159. data/lib/mongoid/railties/database.rake +97 -0
  160. data/lib/mongoid/railties/document.rb +12 -0
  161. data/lib/mongoid/relations.rb +162 -0
  162. data/lib/mongoid/relations/accessors.rb +299 -0
  163. data/lib/mongoid/relations/auto_save.rb +106 -0
  164. data/lib/mongoid/relations/binding.rb +218 -0
  165. data/lib/mongoid/relations/bindings.rb +9 -0
  166. data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
  167. data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
  168. data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
  169. data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
  170. data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
  171. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
  172. data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
  173. data/lib/mongoid/relations/builder.rb +57 -0
  174. data/lib/mongoid/relations/builders.rb +104 -0
  175. data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
  176. data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
  177. data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
  178. data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
  179. data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
  180. data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
  181. data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
  182. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
  183. data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
  184. data/lib/mongoid/relations/cascading.rb +56 -0
  185. data/lib/mongoid/relations/cascading/delete.rb +44 -0
  186. data/lib/mongoid/relations/cascading/destroy.rb +43 -0
  187. data/lib/mongoid/relations/cascading/nullify.rb +35 -0
  188. data/lib/mongoid/relations/cascading/restrict.rb +39 -0
  189. data/lib/mongoid/relations/constraint.rb +49 -0
  190. data/lib/mongoid/relations/conversions.rb +34 -0
  191. data/lib/mongoid/relations/counter_cache.rb +105 -0
  192. data/lib/mongoid/relations/cyclic.rb +107 -0
  193. data/lib/mongoid/relations/embedded/batchable.rb +355 -0
  194. data/lib/mongoid/relations/embedded/in.rb +231 -0
  195. data/lib/mongoid/relations/embedded/many.rb +639 -0
  196. data/lib/mongoid/relations/embedded/one.rb +223 -0
  197. data/lib/mongoid/relations/macros.rb +356 -0
  198. data/lib/mongoid/relations/many.rb +208 -0
  199. data/lib/mongoid/relations/marshalable.rb +32 -0
  200. data/lib/mongoid/relations/metadata.rb +1174 -0
  201. data/lib/mongoid/relations/nested_builder.rb +74 -0
  202. data/lib/mongoid/relations/one.rb +48 -0
  203. data/lib/mongoid/relations/options.rb +48 -0
  204. data/lib/mongoid/relations/polymorphic.rb +39 -0
  205. data/lib/mongoid/relations/proxy.rb +270 -0
  206. data/lib/mongoid/relations/referenced/in.rb +297 -0
  207. data/lib/mongoid/relations/referenced/many.rb +787 -0
  208. data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
  209. data/lib/mongoid/relations/referenced/one.rb +290 -0
  210. data/lib/mongoid/relations/reflections.rb +62 -0
  211. data/lib/mongoid/relations/synchronization.rb +169 -0
  212. data/lib/mongoid/relations/targets.rb +2 -0
  213. data/lib/mongoid/relations/targets/enumerable.rb +473 -0
  214. data/lib/mongoid/relations/touchable.rb +94 -0
  215. data/lib/mongoid/reloadable.rb +95 -0
  216. data/lib/mongoid/scopable.rb +379 -0
  217. data/lib/mongoid/selectable.rb +59 -0
  218. data/lib/mongoid/serializable.rb +170 -0
  219. data/lib/mongoid/sessions.rb +330 -0
  220. data/lib/mongoid/sessions/factory.rb +129 -0
  221. data/lib/mongoid/sessions/mongo_uri.rb +93 -0
  222. data/lib/mongoid/sessions/options.rb +141 -0
  223. data/lib/mongoid/sessions/validators.rb +2 -0
  224. data/lib/mongoid/sessions/validators/storage.rb +49 -0
  225. data/lib/mongoid/shardable.rb +65 -0
  226. data/lib/mongoid/state.rb +97 -0
  227. data/lib/mongoid/threaded.rb +383 -0
  228. data/lib/mongoid/threaded/lifecycle.rb +164 -0
  229. data/lib/mongoid/timestamps.rb +15 -0
  230. data/lib/mongoid/timestamps/created.rb +30 -0
  231. data/lib/mongoid/timestamps/created/short.rb +19 -0
  232. data/lib/mongoid/timestamps/short.rb +10 -0
  233. data/lib/mongoid/timestamps/updated.rb +39 -0
  234. data/lib/mongoid/timestamps/updated/short.rb +19 -0
  235. data/lib/mongoid/traversable.rb +192 -0
  236. data/lib/mongoid/unit_of_work.rb +61 -0
  237. data/lib/mongoid/validatable.rb +180 -0
  238. data/lib/mongoid/validatable/associated.rb +48 -0
  239. data/lib/mongoid/validatable/format.rb +20 -0
  240. data/lib/mongoid/validatable/length.rb +20 -0
  241. data/lib/mongoid/validatable/localizable.rb +30 -0
  242. data/lib/mongoid/validatable/macros.rb +94 -0
  243. data/lib/mongoid/validatable/presence.rb +86 -0
  244. data/lib/mongoid/validatable/queryable.rb +30 -0
  245. data/lib/mongoid/validatable/uniqueness.rb +330 -0
  246. data/lib/mongoid/version.rb +4 -0
  247. data/lib/rack/mongoid.rb +2 -0
  248. data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
  249. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  250. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
  251. data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
  252. data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
  253. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  254. data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
  255. data/lib/rails/generators/mongoid_generator.rb +65 -0
  256. data/lib/rails/mongoid.rb +180 -0
  257. data/lib/support/ruby_version.rb +26 -0
  258. data/spec/app/models/account.rb +28 -0
  259. data/spec/app/models/acolyte.rb +17 -0
  260. data/spec/app/models/actor.rb +18 -0
  261. data/spec/app/models/actress.rb +2 -0
  262. data/spec/app/models/address.rb +77 -0
  263. data/spec/app/models/address_component.rb +5 -0
  264. data/spec/app/models/address_number.rb +6 -0
  265. data/spec/app/models/agency.rb +5 -0
  266. data/spec/app/models/agent.rb +12 -0
  267. data/spec/app/models/album.rb +14 -0
  268. data/spec/app/models/alert.rb +5 -0
  269. data/spec/app/models/animal.rb +25 -0
  270. data/spec/app/models/answer.rb +4 -0
  271. data/spec/app/models/appointment.rb +7 -0
  272. data/spec/app/models/article.rb +10 -0
  273. data/spec/app/models/artist.rb +66 -0
  274. data/spec/app/models/artwork.rb +4 -0
  275. data/spec/app/models/audio.rb +5 -0
  276. data/spec/app/models/augmentation.rb +11 -0
  277. data/spec/app/models/author.rb +4 -0
  278. data/spec/app/models/band.rb +26 -0
  279. data/spec/app/models/bar.rb +10 -0
  280. data/spec/app/models/basic.rb +6 -0
  281. data/spec/app/models/bed.rb +1 -0
  282. data/spec/app/models/big_palette.rb +2 -0
  283. data/spec/app/models/birthday.rb +13 -0
  284. data/spec/app/models/book.rb +13 -0
  285. data/spec/app/models/breed.rb +4 -0
  286. data/spec/app/models/browser.rb +6 -0
  287. data/spec/app/models/building.rb +5 -0
  288. data/spec/app/models/building_address.rb +5 -0
  289. data/spec/app/models/bus.rb +7 -0
  290. data/spec/app/models/business.rb +5 -0
  291. data/spec/app/models/callback_recorder.rb +25 -0
  292. data/spec/app/models/callback_test.rb +9 -0
  293. data/spec/app/models/canvas.rb +25 -0
  294. data/spec/app/models/car.rb +1 -0
  295. data/spec/app/models/cat.rb +8 -0
  296. data/spec/app/models/category.rb +8 -0
  297. data/spec/app/models/child.rb +4 -0
  298. data/spec/app/models/child_doc.rb +22 -0
  299. data/spec/app/models/church.rb +4 -0
  300. data/spec/app/models/circle.rb +3 -0
  301. data/spec/app/models/circuit.rb +4 -0
  302. data/spec/app/models/circus.rb +7 -0
  303. data/spec/app/models/code.rb +5 -0
  304. data/spec/app/models/comment.rb +16 -0
  305. data/spec/app/models/contractor.rb +5 -0
  306. data/spec/app/models/cookie.rb +6 -0
  307. data/spec/app/models/country_code.rb +8 -0
  308. data/spec/app/models/definition.rb +7 -0
  309. data/spec/app/models/description.rb +11 -0
  310. data/spec/app/models/dictionary.rb +10 -0
  311. data/spec/app/models/division.rb +10 -0
  312. data/spec/app/models/doctor.rb +12 -0
  313. data/spec/app/models/dog.rb +7 -0
  314. data/spec/app/models/dokument.rb +5 -0
  315. data/spec/app/models/dragon.rb +4 -0
  316. data/spec/app/models/driver.rb +7 -0
  317. data/spec/app/models/drug.rb +6 -0
  318. data/spec/app/models/dungeon.rb +4 -0
  319. data/spec/app/models/email.rb +6 -0
  320. data/spec/app/models/employer.rb +5 -0
  321. data/spec/app/models/entry.rb +6 -0
  322. data/spec/app/models/eraser.rb +1 -0
  323. data/spec/app/models/event.rb +22 -0
  324. data/spec/app/models/exhibition.rb +4 -0
  325. data/spec/app/models/exhibitor.rb +5 -0
  326. data/spec/app/models/eye.rb +9 -0
  327. data/spec/app/models/eye_bowl.rb +9 -0
  328. data/spec/app/models/face.rb +8 -0
  329. data/spec/app/models/favorite.rb +6 -0
  330. data/spec/app/models/filesystem.rb +5 -0
  331. data/spec/app/models/fire_hydrant.rb +6 -0
  332. data/spec/app/models/firefox.rb +4 -0
  333. data/spec/app/models/fish.rb +7 -0
  334. data/spec/app/models/folder.rb +7 -0
  335. data/spec/app/models/folder_item.rb +9 -0
  336. data/spec/app/models/fruits.rb +28 -0
  337. data/spec/app/models/game.rb +19 -0
  338. data/spec/app/models/ghost.rb +7 -0
  339. data/spec/app/models/home.rb +4 -0
  340. data/spec/app/models/house.rb +6 -0
  341. data/spec/app/models/html_writer.rb +3 -0
  342. data/spec/app/models/image.rb +22 -0
  343. data/spec/app/models/implant.rb +16 -0
  344. data/spec/app/models/item.rb +8 -0
  345. data/spec/app/models/jar.rb +7 -0
  346. data/spec/app/models/label.rb +40 -0
  347. data/spec/app/models/language.rb +5 -0
  348. data/spec/app/models/lat_lng.rb +15 -0
  349. data/spec/app/models/league.rb +11 -0
  350. data/spec/app/models/learner.rb +2 -0
  351. data/spec/app/models/line_item.rb +6 -0
  352. data/spec/app/models/location.rb +8 -0
  353. data/spec/app/models/login.rb +8 -0
  354. data/spec/app/models/manufacturer.rb +7 -0
  355. data/spec/app/models/meat.rb +4 -0
  356. data/spec/app/models/membership.rb +4 -0
  357. data/spec/app/models/mixed_drink.rb +4 -0
  358. data/spec/app/models/movie.rb +13 -0
  359. data/spec/app/models/my_hash.rb +2 -0
  360. data/spec/app/models/name.rb +23 -0
  361. data/spec/app/models/node.rb +5 -0
  362. data/spec/app/models/note.rb +12 -0
  363. data/spec/app/models/ordered_post.rb +6 -0
  364. data/spec/app/models/ordered_preference.rb +6 -0
  365. data/spec/app/models/oscar.rb +15 -0
  366. data/spec/app/models/override.rb +16 -0
  367. data/spec/app/models/ownable.rb +6 -0
  368. data/spec/app/models/owner.rb +6 -0
  369. data/spec/app/models/pack.rb +3 -0
  370. data/spec/app/models/page.rb +5 -0
  371. data/spec/app/models/page_question.rb +4 -0
  372. data/spec/app/models/palette.rb +7 -0
  373. data/spec/app/models/parent.rb +5 -0
  374. data/spec/app/models/parent_doc.rb +6 -0
  375. data/spec/app/models/passport.rb +5 -0
  376. data/spec/app/models/patient.rb +9 -0
  377. data/spec/app/models/pdf_writer.rb +3 -0
  378. data/spec/app/models/pencil.rb +1 -0
  379. data/spec/app/models/person.rb +205 -0
  380. data/spec/app/models/pet.rb +23 -0
  381. data/spec/app/models/pet_owner.rb +6 -0
  382. data/spec/app/models/phone.rb +11 -0
  383. data/spec/app/models/pizza.rb +7 -0
  384. data/spec/app/models/player.rb +35 -0
  385. data/spec/app/models/post.rb +44 -0
  386. data/spec/app/models/powerup.rb +11 -0
  387. data/spec/app/models/preference.rb +9 -0
  388. data/spec/app/models/princess.rb +8 -0
  389. data/spec/app/models/product.rb +15 -0
  390. data/spec/app/models/profile.rb +5 -0
  391. data/spec/app/models/pronunciation.rb +5 -0
  392. data/spec/app/models/purchase.rb +4 -0
  393. data/spec/app/models/question.rb +8 -0
  394. data/spec/app/models/quiz.rb +7 -0
  395. data/spec/app/models/rating.rb +8 -0
  396. data/spec/app/models/record.rb +46 -0
  397. data/spec/app/models/registry.rb +4 -0
  398. data/spec/app/models/role.rb +7 -0
  399. data/spec/app/models/root_category.rb +4 -0
  400. data/spec/app/models/sandwich.rb +4 -0
  401. data/spec/app/models/scheduler.rb +7 -0
  402. data/spec/app/models/seo.rb +7 -0
  403. data/spec/app/models/series.rb +4 -0
  404. data/spec/app/models/server.rb +13 -0
  405. data/spec/app/models/service.rb +22 -0
  406. data/spec/app/models/shape.rb +12 -0
  407. data/spec/app/models/shelf.rb +5 -0
  408. data/spec/app/models/shipping_container.rb +5 -0
  409. data/spec/app/models/shipping_pack.rb +3 -0
  410. data/spec/app/models/shop.rb +6 -0
  411. data/spec/app/models/short_agent.rb +4 -0
  412. data/spec/app/models/short_quiz.rb +5 -0
  413. data/spec/app/models/slave.rb +6 -0
  414. data/spec/app/models/song.rb +8 -0
  415. data/spec/app/models/sound.rb +5 -0
  416. data/spec/app/models/square.rb +4 -0
  417. data/spec/app/models/strategy.rb +3 -0
  418. data/spec/app/models/sub_item.rb +3 -0
  419. data/spec/app/models/subscription.rb +4 -0
  420. data/spec/app/models/survey.rb +5 -0
  421. data/spec/app/models/symptom.rb +6 -0
  422. data/spec/app/models/tag.rb +8 -0
  423. data/spec/app/models/target.rb +5 -0
  424. data/spec/app/models/template.rb +5 -0
  425. data/spec/app/models/thing.rb +9 -0
  426. data/spec/app/models/title.rb +3 -0
  427. data/spec/app/models/tool.rb +8 -0
  428. data/spec/app/models/topping.rb +5 -0
  429. data/spec/app/models/track.rb +38 -0
  430. data/spec/app/models/translation.rb +5 -0
  431. data/spec/app/models/tree.rb +9 -0
  432. data/spec/app/models/truck.rb +3 -0
  433. data/spec/app/models/user.rb +21 -0
  434. data/spec/app/models/user_account.rb +10 -0
  435. data/spec/app/models/validation_callback.rb +10 -0
  436. data/spec/app/models/vehicle.rb +11 -0
  437. data/spec/app/models/version.rb +5 -0
  438. data/spec/app/models/vet_visit.rb +5 -0
  439. data/spec/app/models/video.rb +13 -0
  440. data/spec/app/models/weapon.rb +11 -0
  441. data/spec/app/models/wiki_page.rb +14 -0
  442. data/spec/app/models/word.rb +15 -0
  443. data/spec/app/models/word_origin.rb +11 -0
  444. data/spec/app/models/writer.rb +11 -0
  445. data/spec/config/mongoid.yml +38 -0
  446. data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
  447. data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
  448. data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
  449. data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
  450. data/spec/mongoid/atomic/paths_spec.rb +270 -0
  451. data/spec/mongoid/atomic_spec.rb +365 -0
  452. data/spec/mongoid/attributes/nested_spec.rb +4832 -0
  453. data/spec/mongoid/attributes/readonly_spec.rb +169 -0
  454. data/spec/mongoid/attributes_spec.rb +1412 -0
  455. data/spec/mongoid/changeable_spec.rb +1507 -0
  456. data/spec/mongoid/composable_spec.rb +24 -0
  457. data/spec/mongoid/config/environment_spec.rb +83 -0
  458. data/spec/mongoid/config/options_spec.rb +56 -0
  459. data/spec/mongoid/config_spec.rb +318 -0
  460. data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
  461. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
  462. data/spec/mongoid/contextual/atomic_spec.rb +529 -0
  463. data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
  464. data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
  465. data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
  466. data/spec/mongoid/contextual/memory_spec.rb +1236 -0
  467. data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
  468. data/spec/mongoid/contextual/text_search_spec.rb +207 -0
  469. data/spec/mongoid/copyable_spec.rb +393 -0
  470. data/spec/mongoid/criteria/findable_spec.rb +1189 -0
  471. data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
  472. data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
  473. data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
  474. data/spec/mongoid/criteria/scopable_spec.rb +391 -0
  475. data/spec/mongoid/criteria_spec.rb +3821 -0
  476. data/spec/mongoid/document_spec.rb +1205 -0
  477. data/spec/mongoid/equality_spec.rb +241 -0
  478. data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
  479. data/spec/mongoid/errors/callback_spec.rb +29 -0
  480. data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
  481. data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
  482. data/spec/mongoid/errors/eager_load_spec.rb +29 -0
  483. data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
  484. data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
  485. data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
  486. data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
  487. data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
  488. data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
  489. data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
  490. data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
  491. data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
  492. data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
  493. data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
  494. data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
  495. data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
  496. data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
  497. data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
  498. data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
  499. data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
  500. data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
  501. data/spec/mongoid/errors/no_environment_spec.rb +29 -0
  502. data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
  503. data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
  504. data/spec/mongoid/errors/no_parent_spec.rb +29 -0
  505. data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
  506. data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
  507. data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
  508. data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
  509. data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
  510. data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
  511. data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
  512. data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
  513. data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
  514. data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
  515. data/spec/mongoid/errors/validations_spec.rb +45 -0
  516. data/spec/mongoid/extensions/array_spec.rb +638 -0
  517. data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
  518. data/spec/mongoid/extensions/binary_spec.rb +60 -0
  519. data/spec/mongoid/extensions/boolean_spec.rb +135 -0
  520. data/spec/mongoid/extensions/date_spec.rb +235 -0
  521. data/spec/mongoid/extensions/date_time_spec.rb +155 -0
  522. data/spec/mongoid/extensions/false_class_spec.rb +42 -0
  523. data/spec/mongoid/extensions/float_spec.rb +133 -0
  524. data/spec/mongoid/extensions/hash_spec.rb +333 -0
  525. data/spec/mongoid/extensions/integer_spec.rb +136 -0
  526. data/spec/mongoid/extensions/module_spec.rb +42 -0
  527. data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
  528. data/spec/mongoid/extensions/object_id_spec.rb +946 -0
  529. data/spec/mongoid/extensions/object_spec.rb +292 -0
  530. data/spec/mongoid/extensions/range_spec.rb +105 -0
  531. data/spec/mongoid/extensions/regexp_spec.rb +47 -0
  532. data/spec/mongoid/extensions/set_spec.rb +33 -0
  533. data/spec/mongoid/extensions/string_spec.rb +357 -0
  534. data/spec/mongoid/extensions/symbol_spec.rb +76 -0
  535. data/spec/mongoid/extensions/time_spec.rb +467 -0
  536. data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
  537. data/spec/mongoid/extensions/true_class_spec.rb +42 -0
  538. data/spec/mongoid/extensions_spec.rb +15 -0
  539. data/spec/mongoid/factory_spec.rb +185 -0
  540. data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
  541. data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
  542. data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
  543. data/spec/mongoid/fields/localized_spec.rb +386 -0
  544. data/spec/mongoid/fields/standard_spec.rb +166 -0
  545. data/spec/mongoid/fields_spec.rb +1229 -0
  546. data/spec/mongoid/findable_spec.rb +342 -0
  547. data/spec/mongoid/identity_map_spec.rb +564 -0
  548. data/spec/mongoid/indexable/specification_spec.rb +87 -0
  549. data/spec/mongoid/indexable_spec.rb +504 -0
  550. data/spec/mongoid/inspectable_spec.rb +49 -0
  551. data/spec/mongoid/interceptable_spec.rb +1564 -0
  552. data/spec/mongoid/loggable_spec.rb +21 -0
  553. data/spec/mongoid/matchable/all_spec.rb +31 -0
  554. data/spec/mongoid/matchable/and_spec.rb +162 -0
  555. data/spec/mongoid/matchable/default_spec.rb +130 -0
  556. data/spec/mongoid/matchable/exists_spec.rb +57 -0
  557. data/spec/mongoid/matchable/gt_spec.rb +75 -0
  558. data/spec/mongoid/matchable/gte_spec.rb +74 -0
  559. data/spec/mongoid/matchable/in_spec.rb +25 -0
  560. data/spec/mongoid/matchable/lt_spec.rb +74 -0
  561. data/spec/mongoid/matchable/lte_spec.rb +74 -0
  562. data/spec/mongoid/matchable/ne_spec.rb +25 -0
  563. data/spec/mongoid/matchable/nin_spec.rb +25 -0
  564. data/spec/mongoid/matchable/or_spec.rb +106 -0
  565. data/spec/mongoid/matchable/size_spec.rb +25 -0
  566. data/spec/mongoid/matchable_spec.rb +532 -0
  567. data/spec/mongoid/persistable/creatable_spec.rb +512 -0
  568. data/spec/mongoid/persistable/deletable_spec.rb +205 -0
  569. data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
  570. data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
  571. data/spec/mongoid/persistable/logical_spec.rb +143 -0
  572. data/spec/mongoid/persistable/poppable_spec.rb +115 -0
  573. data/spec/mongoid/persistable/pullable_spec.rb +228 -0
  574. data/spec/mongoid/persistable/pushable_spec.rb +258 -0
  575. data/spec/mongoid/persistable/renamable_spec.rb +135 -0
  576. data/spec/mongoid/persistable/savable_spec.rb +432 -0
  577. data/spec/mongoid/persistable/settable_spec.rb +139 -0
  578. data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
  579. data/spec/mongoid/persistable/updatable_spec.rb +522 -0
  580. data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
  581. data/spec/mongoid/persistable_spec.rb +206 -0
  582. data/spec/mongoid/positional_spec.rb +227 -0
  583. data/spec/mongoid/railties/document_spec.rb +24 -0
  584. data/spec/mongoid/relations/accessors_spec.rb +736 -0
  585. data/spec/mongoid/relations/auto_save_spec.rb +261 -0
  586. data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
  587. data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
  588. data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
  589. data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
  590. data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
  591. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
  592. data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
  593. data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
  594. data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
  595. data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
  596. data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
  597. data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
  598. data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
  599. data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
  600. data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
  601. data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
  602. data/spec/mongoid/relations/builders_spec.rb +226 -0
  603. data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
  604. data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
  605. data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
  606. data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
  607. data/spec/mongoid/relations/cascading_spec.rb +355 -0
  608. data/spec/mongoid/relations/constraint_spec.rb +74 -0
  609. data/spec/mongoid/relations/conversions_spec.rb +126 -0
  610. data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
  611. data/spec/mongoid/relations/cyclic_spec.rb +156 -0
  612. data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
  613. data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
  614. data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
  615. data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
  616. data/spec/mongoid/relations/macros_spec.rb +613 -0
  617. data/spec/mongoid/relations/metadata_spec.rb +1917 -0
  618. data/spec/mongoid/relations/options_spec.rb +35 -0
  619. data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
  620. data/spec/mongoid/relations/proxy_spec.rb +48 -0
  621. data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
  622. data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
  623. data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
  624. data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
  625. data/spec/mongoid/relations/reflections_spec.rb +101 -0
  626. data/spec/mongoid/relations/synchronization_spec.rb +449 -0
  627. data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
  628. data/spec/mongoid/relations/touchable_spec.rb +296 -0
  629. data/spec/mongoid/relations_spec.rb +188 -0
  630. data/spec/mongoid/reloadable_spec.rb +305 -0
  631. data/spec/mongoid/scopable_spec.rb +926 -0
  632. data/spec/mongoid/selectable_spec.rb +134 -0
  633. data/spec/mongoid/serializable_spec.rb +862 -0
  634. data/spec/mongoid/sessions/factory_spec.rb +312 -0
  635. data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
  636. data/spec/mongoid/sessions/options_spec.rb +71 -0
  637. data/spec/mongoid/sessions_spec.rb +1078 -0
  638. data/spec/mongoid/shardable_spec.rb +61 -0
  639. data/spec/mongoid/state_spec.rb +102 -0
  640. data/spec/mongoid/threaded_spec.rb +258 -0
  641. data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
  642. data/spec/mongoid/timestamps/created_spec.rb +44 -0
  643. data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
  644. data/spec/mongoid/timestamps/updated_spec.rb +86 -0
  645. data/spec/mongoid/timestamps_spec.rb +112 -0
  646. data/spec/mongoid/traversable_spec.rb +244 -0
  647. data/spec/mongoid/unit_of_work_spec.rb +196 -0
  648. data/spec/mongoid/validatable/associated_spec.rb +183 -0
  649. data/spec/mongoid/validatable/format_spec.rb +83 -0
  650. data/spec/mongoid/validatable/length_spec.rb +119 -0
  651. data/spec/mongoid/validatable/numericality_spec.rb +30 -0
  652. data/spec/mongoid/validatable/presence_spec.rb +511 -0
  653. data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
  654. data/spec/mongoid/validatable_spec.rb +309 -0
  655. data/spec/mongoid_spec.rb +74 -0
  656. data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
  657. data/spec/rails/mongoid_spec.rb +462 -0
  658. data/spec/spec_helper.rb +103 -0
  659. metadata +1159 -0
@@ -0,0 +1,166 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields::Standard do
4
+
5
+ describe "#lazy?" do
6
+
7
+ let(:field) do
8
+ described_class.new(:test, type: String)
9
+ end
10
+
11
+ it "returns false" do
12
+ expect(field).to_not be_lazy
13
+ end
14
+ end
15
+
16
+ describe "#pre_processed?" do
17
+
18
+ before(:all) do
19
+ class FieldTest
20
+ include Mongoid::Document
21
+ end
22
+ end
23
+
24
+ after(:all) do
25
+ Object.send(:remove_const, :FieldTest)
26
+ end
27
+
28
+ context "when the field has a default" do
29
+
30
+ context "when the default is a proc" do
31
+
32
+ context "when the pre-processed option is true" do
33
+
34
+ let(:field) do
35
+ described_class.new(
36
+ :test,
37
+ default: ->{ "testing" },
38
+ pre_processed: true,
39
+ klass: FieldTest,
40
+ type: String
41
+ )
42
+ end
43
+
44
+ it "returns true" do
45
+ expect(field).to be_pre_processed
46
+ end
47
+ end
48
+
49
+ context "when the pre-processed option is not true" do
50
+
51
+ let(:field) do
52
+ described_class.new(
53
+ :test,
54
+ default: ->{ "testing" },
55
+ klass: FieldTest,
56
+ type: String
57
+ )
58
+ end
59
+
60
+ it "returns false" do
61
+ expect(field).to_not be_pre_processed
62
+ end
63
+ end
64
+ end
65
+
66
+ context "when the default is not a proc" do
67
+
68
+ let(:field) do
69
+ described_class.new(
70
+ :test,
71
+ default: "testing",
72
+ klass: FieldTest,
73
+ type: String
74
+ )
75
+ end
76
+
77
+ it "returns true" do
78
+ expect(field).to be_pre_processed
79
+ end
80
+ end
81
+ end
82
+
83
+ context "when the field has no default" do
84
+
85
+ let(:field) do
86
+ described_class.new(
87
+ :test,
88
+ type: String
89
+ )
90
+ end
91
+
92
+ it "returns false" do
93
+ expect(field).to_not be_pre_processed
94
+ end
95
+ end
96
+ end
97
+
98
+ context "when checking hash values in a custom serializer" do
99
+
100
+ let(:image) do
101
+ Image.new("test")
102
+ end
103
+
104
+ it "does not conflict with the ruby core hash" do
105
+ expect(image.hash_is_hash).to be_true
106
+ end
107
+ end
108
+
109
+ context "when included in a hash" do
110
+
111
+ let(:hash) do
112
+ MyHash.new
113
+ end
114
+
115
+ context "when setting a value" do
116
+
117
+ before do
118
+ hash[:key] = "value"
119
+ end
120
+
121
+ it "allows normal hash access" do
122
+ expect(hash[:key]).to eq("value")
123
+ end
124
+ end
125
+
126
+ context "when getting a non existant value" do
127
+
128
+ it "returns nil" do
129
+ expect(hash[:key]).to be_nil
130
+ end
131
+ end
132
+ end
133
+
134
+ context "when subclassing a serializable field" do
135
+
136
+ let(:thumbnail) do
137
+ Thumbnail.new("test")
138
+ end
139
+
140
+ it "inherits the parents deserialize method" do
141
+ expect(Thumbnail.demongoize("testy").name).to eq("testy")
142
+ end
143
+
144
+ it "inherits the parents serialize method" do
145
+ expect(thumbnail.mongoize).to eq("test")
146
+ end
147
+
148
+ context "when instantiating the class" do
149
+
150
+ let(:movie) do
151
+ Movie.new(
152
+ poster: Image.new("poster"),
153
+ poster_thumb: Thumbnail.new("thumb")
154
+ )
155
+ end
156
+
157
+ it "deserializes the parent type" do
158
+ expect(movie.poster.name).to eq("poster")
159
+ end
160
+
161
+ it "deserializes the child type" do
162
+ expect(movie.poster_thumb.name).to eq("thumb")
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,1229 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Fields do
4
+
5
+ before(:all) do
6
+ Mongoid.use_activesupport_time_zone = false
7
+ end
8
+
9
+ describe "#\{field}_translations" do
10
+
11
+ let(:product) do
12
+ Product.new
13
+ end
14
+
15
+ context "when the field is localized" do
16
+
17
+ context "when translations exist" do
18
+
19
+ before do
20
+ product.description = "test"
21
+ ::I18n.locale = :de
22
+ product.description = "The best"
23
+ end
24
+
25
+ after do
26
+ ::I18n.locale = :en
27
+ end
28
+
29
+ let(:translations) do
30
+ product.description_translations
31
+ end
32
+
33
+ it "returns all the translations" do
34
+ expect(translations).to eq(
35
+ { "en" => "test", "de" => "The best" }
36
+ )
37
+ end
38
+
39
+ it "returns translations as a HashWithIndifferentAccess" do
40
+ expect(translations[:en]).to eq("test")
41
+ end
42
+ end
43
+
44
+ context "when translations do not exist" do
45
+
46
+ context "when no default is provided" do
47
+
48
+ it "returns an empty hash" do
49
+ expect(product.description_translations).to be_empty
50
+ end
51
+ end
52
+
53
+ context "when a default is provided" do
54
+
55
+ it "returns the translations with the default" do
56
+ expect(product.name_translations).to eq(
57
+ { "en" => "no translation" }
58
+ )
59
+ end
60
+ end
61
+ end
62
+
63
+ it "should have alias method #\{field}_t" do
64
+ product.method(:name_t).should eq product.method(:name_translations)
65
+ end
66
+ end
67
+
68
+ context "when the field is not localized" do
69
+
70
+ it "does not respond to the method" do
71
+ expect(product).to_not respond_to(:price_translations)
72
+ end
73
+
74
+ it "does not respond to the alias method" do
75
+ product.should_not respond_to(:price_t)
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "#\{field}_translations=" do
81
+
82
+ let(:product) do
83
+ Product.new
84
+ end
85
+
86
+ let(:dictionary) do
87
+ Dictionary.new
88
+ end
89
+
90
+ context "when the field is localized" do
91
+
92
+ context "when the field does not require mongoizations" do
93
+
94
+ let(:translations) do
95
+ { "en" => "test", "de" => "testing" }
96
+ end
97
+
98
+ before do
99
+ product.description_translations = translations
100
+ end
101
+
102
+ it "sets the raw values of the translations" do
103
+ expect(product.description_translations).to eq(translations)
104
+ end
105
+
106
+ context "when saving the new translations" do
107
+
108
+ before do
109
+ product.save
110
+ end
111
+
112
+ it "persists the changes" do
113
+ expect(product.reload.description_translations).to eq(translations)
114
+ end
115
+
116
+ context "when updating the translations" do
117
+
118
+ before do
119
+ product.description_translations = { "en" => "overwritten" }
120
+ product.save
121
+ end
122
+
123
+ it "persists the changes" do
124
+ expect(product.reload.description_translations).to eq(
125
+ { "en" => "overwritten" }
126
+ )
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ context "when the field requires mongoization" do
133
+
134
+ let(:translations) do
135
+ { "en" => 1, "de" => 2 }
136
+ end
137
+
138
+ before do
139
+ dictionary.description_translations = translations
140
+ end
141
+
142
+ it "sets the mongoized values of the translations" do
143
+ expect(dictionary.description_translations).to eq(
144
+ { "en" => "1", "de" => "2" }
145
+ )
146
+ end
147
+
148
+ context "when saving the new translations" do
149
+
150
+ before do
151
+ dictionary.save
152
+ end
153
+
154
+ it "persists the changes" do
155
+ expect(dictionary.reload.description_translations).to eq(
156
+ { "en" => "1", "de" => "2" }
157
+ )
158
+ end
159
+
160
+ context "when updating the translations" do
161
+
162
+ before do
163
+ dictionary.description_translations = { "en" => "overwritten" }
164
+ dictionary.save
165
+ end
166
+
167
+ it "persists the changes" do
168
+ expect(dictionary.reload.description_translations).to eq(
169
+ { "en" => "overwritten" }
170
+ )
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ it "should have alias method #\{field}_t=" do
177
+ product.method(:name_t=).should eq product.method(:name_translations=)
178
+ end
179
+ end
180
+
181
+ context "when the field is not localized" do
182
+
183
+ it "does not respond to the method" do
184
+ expect(product).to_not respond_to(:price_translations=)
185
+ end
186
+
187
+ it "does not respond to the alias method" do
188
+ product.should_not respond_to(:price_t=)
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "#aliased_fields" do
194
+
195
+ let(:person) do
196
+ Person.new
197
+ end
198
+
199
+ context "when the document is subclassed" do
200
+
201
+ it "does not include the child aliases" do
202
+ expect(person.aliased_fields.keys).to_not include("spec")
203
+ end
204
+ end
205
+ end
206
+
207
+ describe "#attribute_names" do
208
+
209
+ context "when the document is a parent class" do
210
+
211
+ let(:shape) do
212
+ Shape.new
213
+ end
214
+
215
+ it "includes the _id field" do
216
+ expect(shape.attribute_names).to include("_id")
217
+ end
218
+
219
+ it "includes the _type field" do
220
+ expect(shape.attribute_names).to include("_type")
221
+ end
222
+
223
+ it "includes its own fields" do
224
+ expect(shape.attribute_names).to include("x")
225
+ end
226
+
227
+ it "does not return subclass fields" do
228
+ expect(shape.attribute_names).to_not include("radius")
229
+ end
230
+ end
231
+
232
+ context "when the document is a subclass" do
233
+
234
+ let(:circle) do
235
+ Circle.new
236
+ end
237
+
238
+ it "includes the _id field" do
239
+ expect(circle.attribute_names).to include("_id")
240
+ end
241
+
242
+ it "includes the _type field" do
243
+ expect(circle.attribute_names).to include("_type")
244
+ end
245
+
246
+ it "includes the first parent field" do
247
+ expect(circle.attribute_names).to include("x")
248
+ end
249
+
250
+ it "includes the second parent field" do
251
+ expect(circle.attribute_names).to include("y")
252
+ end
253
+
254
+ it "includes the child fields" do
255
+ expect(circle.attribute_names).to include("radius")
256
+ end
257
+ end
258
+ end
259
+
260
+ describe ".attribute_names" do
261
+
262
+ context "when the class is a parent" do
263
+
264
+ it "includes the _id field" do
265
+ expect(Shape.attribute_names).to include("_id")
266
+ end
267
+
268
+ it "includes the _type field" do
269
+ expect(Shape.attribute_names).to include("_type")
270
+ end
271
+
272
+ it "includes its own fields" do
273
+ expect(Shape.attribute_names).to include("x")
274
+ end
275
+
276
+ it "does not return subclass fields" do
277
+ expect(Shape.attribute_names).to_not include("radius")
278
+ end
279
+ end
280
+
281
+ context "when the class is a subclass" do
282
+
283
+ it "includes the _id field" do
284
+ expect(Circle.attribute_names).to include("_id")
285
+ end
286
+
287
+ it "includes the _type field" do
288
+ expect(Circle.attribute_names).to include("_type")
289
+ end
290
+
291
+ it "includes the first parent field" do
292
+ expect(Circle.attribute_names).to include("x")
293
+ end
294
+
295
+ it "includes the second parent field" do
296
+ expect(Circle.attribute_names).to include("y")
297
+ end
298
+
299
+ it "includes the child fields" do
300
+ expect(Circle.attribute_names).to include("radius")
301
+ end
302
+ end
303
+ end
304
+
305
+ describe "#field" do
306
+
307
+ before(:all) do
308
+ Mongoid::Fields.option :custom do |model, field, value|
309
+ end
310
+ end
311
+
312
+ context "when the options are valid" do
313
+
314
+ context "when the options are all standard" do
315
+
316
+ before do
317
+ Band.field :acceptable, type: Boolean
318
+ end
319
+
320
+ after do
321
+ Band.fields.delete("acceptable")
322
+ end
323
+
324
+ it "adds the field to the model" do
325
+ expect(Band.fields["acceptable"]).to_not be_nil
326
+ end
327
+ end
328
+
329
+ context "when a custom option is provided" do
330
+
331
+ before do
332
+ Band.field :acceptable, type: Boolean, custom: true
333
+ end
334
+
335
+ it "adds the field to the model" do
336
+ expect(Band.fields["acceptable"]).to_not be_nil
337
+ end
338
+ end
339
+ end
340
+
341
+ context "when the options are not valid" do
342
+
343
+ it "raises an error" do
344
+ expect {
345
+ Band.field :unacceptable, bad: true
346
+ }.to raise_error(Mongoid::Errors::InvalidFieldOption)
347
+ end
348
+ end
349
+ end
350
+
351
+ describe "#getter" do
352
+
353
+ context "when the field is binary" do
354
+
355
+ let(:binary) do
356
+ Moped::BSON::Binary.new(:md5, "testing")
357
+ end
358
+
359
+ let(:registry) do
360
+ Registry.new(data: binary)
361
+ end
362
+
363
+ it "returns the binary data intact" do
364
+ expect(registry.data).to eq(binary)
365
+ end
366
+ end
367
+
368
+ context "when a field is localized" do
369
+
370
+ let(:product) do
371
+ Product.new
372
+ end
373
+
374
+ context "when no locale is set" do
375
+
376
+ before do
377
+ product.description = "The best"
378
+ end
379
+
380
+ let(:description) do
381
+ product.description
382
+ end
383
+
384
+ it "returns the default locale value" do
385
+ expect(description).to eq("The best")
386
+ end
387
+ end
388
+
389
+ context "when a single locale is set" do
390
+
391
+ before do
392
+ ::I18n.locale = :de
393
+ product.description = "The best"
394
+ end
395
+
396
+ after do
397
+ ::I18n.locale = :en
398
+ end
399
+
400
+ let(:description) do
401
+ product.description
402
+ end
403
+
404
+ it "returns the set locale value" do
405
+ expect(description).to eq("The best")
406
+ end
407
+ end
408
+
409
+ context "when multiple locales are set" do
410
+
411
+ before do
412
+ product.description = "Cheap drinks"
413
+ ::I18n.locale = :de
414
+ product.description = "Cheaper drinks"
415
+ end
416
+
417
+ after do
418
+ ::I18n.locale = :en
419
+ end
420
+
421
+ let(:description) do
422
+ product.description
423
+ end
424
+
425
+ it "returns the current locale value" do
426
+ expect(description).to eq("Cheaper drinks")
427
+ end
428
+ end
429
+ end
430
+ end
431
+
432
+ describe "#getter_before_type_cast" do
433
+ let(:person) do
434
+ Person.new
435
+ end
436
+
437
+ context "when the attribute has not been assigned" do
438
+
439
+ it "delgates to the getter" do
440
+ expect(person.age_before_type_cast).to eq(person.age)
441
+ end
442
+ end
443
+
444
+ context "when the attribute has been assigned" do
445
+
446
+ it "returns the attribute before type cast" do
447
+ person.age = "old"
448
+ expect(person.age_before_type_cast).to eq("old")
449
+ end
450
+ end
451
+ end
452
+
453
+ describe "#setter=" do
454
+
455
+ let(:product) do
456
+ Product.new
457
+ end
458
+
459
+ context "when setting via the setter" do
460
+
461
+ it "returns the set value" do
462
+ expect(product.price = 10).to eq(10)
463
+ end
464
+ end
465
+
466
+ context "when setting via send" do
467
+
468
+ it "returns the set value" do
469
+ expect(product.send(:price=, 10)).to eq(10)
470
+ end
471
+ end
472
+
473
+ context "when the field is binary" do
474
+
475
+ let(:binary) do
476
+ Moped::BSON::Binary.new(:md5, "testing")
477
+ end
478
+
479
+ let(:registry) do
480
+ Registry.new
481
+ end
482
+
483
+ before do
484
+ registry.data = binary
485
+ end
486
+
487
+ it "returns the binary data intact" do
488
+ expect(registry.data).to eq(binary)
489
+ end
490
+ end
491
+
492
+ context "when the field is an array" do
493
+
494
+ before do
495
+ product.stores = [ "kadewe", "karstadt" ]
496
+ product.save
497
+ end
498
+
499
+ context "when setting the value to nil" do
500
+
501
+ before do
502
+ product.stores = nil
503
+ product.save
504
+ end
505
+
506
+ it "allows the set" do
507
+ expect(product.stores).to be_nil
508
+ end
509
+ end
510
+
511
+ context "when setting any of the values to nil" do
512
+
513
+ before do
514
+ product.stores = [ "kadewe", nil ]
515
+ product.save
516
+ end
517
+
518
+ it "allows the set of nil values" do
519
+ expect(product.stores).to eq([ "kadewe", nil ])
520
+ end
521
+
522
+ it "persists the nil values" do
523
+ expect(product.reload.stores).to eq([ "kadewe", nil ])
524
+ end
525
+ end
526
+
527
+ context "when reversing the array values" do
528
+
529
+ before do
530
+ product.stores = [ "karstadt", "kadewe" ]
531
+ product.save
532
+ end
533
+
534
+ it "reverses the values" do
535
+ expect(product.stores).to eq([ "karstadt", "kadewe" ])
536
+ end
537
+
538
+ it "persists the changes" do
539
+ expect(product.reload.stores).to eq([ "karstadt", "kadewe" ])
540
+ end
541
+ end
542
+ end
543
+
544
+ context "when a field is localized" do
545
+
546
+ context "when no locale is set" do
547
+
548
+ before do
549
+ product.description = "Cheap drinks"
550
+ end
551
+
552
+ let(:description) do
553
+ product.attributes["description"]
554
+ end
555
+
556
+ it "sets the value in the default locale" do
557
+ expect(description).to eq({ "en" => "Cheap drinks" })
558
+ end
559
+ end
560
+
561
+ context "when a locale is set" do
562
+
563
+ before do
564
+ ::I18n.locale = :de
565
+ product.description = "Cheaper drinks"
566
+ end
567
+
568
+ after do
569
+ ::I18n.locale = :en
570
+ end
571
+
572
+ let(:description) do
573
+ product.attributes["description"]
574
+ end
575
+
576
+ it "sets the value in the default locale" do
577
+ expect(description).to eq({ "de" => "Cheaper drinks" })
578
+ end
579
+ end
580
+
581
+ context "when having multiple locales" do
582
+
583
+ before do
584
+ product.description = "Cheap drinks"
585
+ ::I18n.locale = :de
586
+ product.description = "Cheaper drinks"
587
+ end
588
+
589
+ after do
590
+ ::I18n.locale = :en
591
+ end
592
+
593
+ let(:description) do
594
+ product.attributes["description"]
595
+ end
596
+
597
+ it "sets the value in both locales" do
598
+ expect(description).to eq(
599
+ { "de" => "Cheaper drinks", "en" => "Cheap drinks" }
600
+ )
601
+ end
602
+ end
603
+ end
604
+ end
605
+
606
+ describe "#defaults" do
607
+
608
+ context "with defaults specified as a non-primitive" do
609
+
610
+ let(:person_one) do
611
+ Person.new
612
+ end
613
+
614
+ let(:person_two) do
615
+ Person.new
616
+ end
617
+
618
+ context "when provided a default array" do
619
+
620
+ before do
621
+ Person.field(:array_testing, type: Array, default: [])
622
+ end
623
+
624
+ after do
625
+ Person.fields.delete("array_testing")
626
+ Person.pre_processed_defaults.delete_one("array_testing")
627
+ end
628
+
629
+ it "returns an equal object of a different instance" do
630
+ expect(person_one.array_testing.object_id).to_not eq(
631
+ person_two.array_testing.object_id
632
+ )
633
+ end
634
+ end
635
+
636
+ context "when provided a default hash" do
637
+
638
+ before do
639
+ Person.field(:hash_testing, type: Hash, default: {})
640
+ end
641
+
642
+ after do
643
+ Person.fields.delete("hash_testing")
644
+ end
645
+
646
+ it "returns an equal object of a different instance" do
647
+ expect(person_one.hash_testing.object_id).to_not eq(
648
+ person_two.hash_testing.object_id
649
+ )
650
+ end
651
+ end
652
+
653
+ context "when provided a default proc" do
654
+
655
+ context "when the proc has no argument" do
656
+
657
+ before do
658
+ Person.field(
659
+ :generated_testing,
660
+ type: Float,
661
+ default: ->{ Time.now.to_f }
662
+ )
663
+ end
664
+
665
+ after do
666
+ Person.fields.delete("generated_testing")
667
+ Person.pre_processed_defaults.delete_one("generated_testing")
668
+ end
669
+
670
+ it "returns an equal object of a different instance" do
671
+ expect(person_one.generated_testing.object_id).to_not eq(
672
+ person_two.generated_testing.object_id
673
+ )
674
+ end
675
+ end
676
+
677
+ context "when the proc has to be evaluated on the document" do
678
+
679
+ before do
680
+ Person.field(
681
+ :rank,
682
+ type: Integer,
683
+ default: ->{ title? ? 1 : 2 }
684
+ )
685
+ end
686
+
687
+ after do
688
+ Person.fields.delete("rank")
689
+ Person.post_processed_defaults.delete_one("rank")
690
+ end
691
+
692
+ it "yields the document to the proc" do
693
+ expect(Person.new.rank).to eq(2)
694
+ end
695
+ end
696
+ end
697
+ end
698
+
699
+ context "on parent classes" do
700
+
701
+ let(:shape) do
702
+ Shape.new
703
+ end
704
+
705
+ it "does not return subclass defaults" do
706
+ expect(shape.pre_processed_defaults).to eq([ "_id", "x", "y", "_type" ])
707
+ end
708
+ end
709
+
710
+ context "on subclasses" do
711
+
712
+ let(:circle) do
713
+ Circle.new
714
+ end
715
+
716
+ it "has the parent and child defaults" do
717
+ expect(circle.pre_processed_defaults).to eq([ "_id", "x", "y", "_type", "radius" ])
718
+ end
719
+ end
720
+ end
721
+
722
+ describe ".field" do
723
+
724
+ it "returns the generated field" do
725
+ expect(Person.field(:testing)).to eq(Person.fields["testing"])
726
+ end
727
+
728
+ context "when the field name conflicts with mongoid's internals" do
729
+
730
+ context "when the field is named metadata" do
731
+
732
+ it "raises an error" do
733
+ expect {
734
+ Person.field(:metadata)
735
+ }.to raise_error(Mongoid::Errors::InvalidField)
736
+ end
737
+ end
738
+ end
739
+
740
+ context "when field already exist and validate_duplicate is enable" do
741
+
742
+ before do
743
+ Mongoid.duplicate_fields_exception = true
744
+ end
745
+
746
+ after do
747
+ Mongoid.duplicate_fields_exception = false
748
+ end
749
+
750
+ it "raises an error" do
751
+ expect {
752
+ Person.field(:title)
753
+ }.to raise_error(Mongoid::Errors::InvalidField)
754
+ end
755
+
756
+ it "doesn't raise an error" do
757
+ expect {
758
+ Class.new(Person)
759
+ }.to_not raise_error(Mongoid::Errors::InvalidField)
760
+ end
761
+ end
762
+
763
+ context "when the field is a time" do
764
+
765
+ let!(:time) do
766
+ Time.now
767
+ end
768
+
769
+ let!(:person) do
770
+ Person.new(lunch_time: time.utc)
771
+ end
772
+
773
+ context "when reading the field" do
774
+
775
+ before do
776
+ Time.zone = "Berlin"
777
+ end
778
+
779
+ after do
780
+ Time.zone = nil
781
+ end
782
+
783
+ it "performs the necessary time conversions" do
784
+ expect(person.lunch_time.to_s).to eq(time.getlocal.to_s)
785
+ end
786
+ end
787
+ end
788
+
789
+ context "when providing no options" do
790
+
791
+ before do
792
+ Person.field(:testing)
793
+ end
794
+
795
+ let(:person) do
796
+ Person.new(testing: "Test")
797
+ end
798
+
799
+ it "adds a reader for the fields defined" do
800
+ expect(person.testing).to eq("Test")
801
+ end
802
+
803
+ it "adds a writer for the fields defined" do
804
+ (person.testing = expect("Testy")).to eq("Testy")
805
+ end
806
+
807
+ it "adds an existance method" do
808
+ expect(Person.new.testing?).to be_false
809
+ end
810
+
811
+ context "when overwriting an existing field" do
812
+
813
+ before do
814
+ Person.class_eval do
815
+ attr_reader :testing_override_called
816
+ def testing=(value)
817
+ @testing_override_called = true
818
+ super
819
+ end
820
+ end
821
+ person.testing = 'Test'
822
+ end
823
+
824
+ it "properly overwrites the method" do
825
+ expect(person.testing_override_called).to be_true
826
+ end
827
+ end
828
+ end
829
+
830
+ context "when the type is an object" do
831
+
832
+ let(:bob) do
833
+ Person.new(reading: 10.023)
834
+ end
835
+
836
+ it "returns the given value" do
837
+ expect(bob.reading).to eq(10.023)
838
+ end
839
+ end
840
+
841
+ context "when type is a boolean" do
842
+
843
+ let(:person) do
844
+ Person.new(terms: true)
845
+ end
846
+
847
+ it "adds an accessor method with a question mark" do
848
+ expect(person.terms?).to be_true
849
+ end
850
+ end
851
+
852
+ context "when as is specified" do
853
+
854
+ let(:person) do
855
+ Person.new(alias: true)
856
+ end
857
+
858
+ before do
859
+ Person.field :aliased, as: :alias, type: Boolean
860
+ end
861
+
862
+ it "uses the alias to write the attribute" do
863
+ (person.alias = expect(true)).to be_true
864
+ end
865
+
866
+ it "uses the alias to read the attribute" do
867
+ expect(person.alias).to be_true
868
+ end
869
+
870
+ it "uses the alias for the query method" do
871
+ expect(person).to be_alias
872
+ end
873
+
874
+ it "uses the name to write the attribute" do
875
+ (person.aliased = expect(true)).to be_true
876
+ end
877
+
878
+ it "uses the name to read the attribute" do
879
+ expect(person.aliased).to be_true
880
+ end
881
+
882
+ it "uses the name for the query method" do
883
+ expect(person).to be_aliased
884
+ end
885
+
886
+ it "creates dirty methods for the name" do
887
+ expect(person).to respond_to(:aliased_changed?)
888
+ end
889
+
890
+ it "creates dirty methods for the alias" do
891
+ expect(person).to respond_to(:alias_changed?)
892
+ end
893
+
894
+ context "when changing the name" do
895
+
896
+ before do
897
+ person.aliased = true
898
+ end
899
+
900
+ it "sets name_changed?" do
901
+ expect(person.aliased_changed?).to be_true
902
+ end
903
+
904
+ it "sets alias_changed?" do
905
+ expect(person.alias_changed?).to be_true
906
+ end
907
+ end
908
+
909
+ context "when changing the alias" do
910
+
911
+ before do
912
+ person.alias = true
913
+ end
914
+
915
+ it "sets name_changed?" do
916
+ expect(person.aliased_changed?).to be_true
917
+ end
918
+
919
+ it "sets alias_changed?" do
920
+ expect(person.alias_changed?).to be_true
921
+ end
922
+ end
923
+
924
+ context "when defining a criteria" do
925
+
926
+ let(:criteria) do
927
+ Person.where(alias: "true")
928
+ end
929
+
930
+ it "properly serializes the aliased field" do
931
+ expect(criteria.selector).to eq({ "aliased" => true })
932
+ end
933
+ end
934
+ end
935
+
936
+ context "custom options" do
937
+
938
+ let(:handler) do
939
+ proc {}
940
+ end
941
+
942
+ before do
943
+ Mongoid::Fields.option :option, &handler
944
+ end
945
+
946
+ context "when option is provided" do
947
+
948
+ it "calls the handler with the model" do
949
+ handler.should_receive(:call).with do |model,_,_|
950
+ expect(model).to eql User
951
+ end
952
+
953
+ User.field :custom, option: true
954
+ end
955
+
956
+ it "calls the handler with the field" do
957
+ handler.should_receive(:call).with do |_,field,_|
958
+ expect(field).to eql User.fields["custom"]
959
+ end
960
+
961
+ User.field :custom, option: true
962
+ end
963
+
964
+ it "calls the handler with the option value" do
965
+ handler.should_receive(:call).with do |_,_,value|
966
+ expect(value).to eql true
967
+ end
968
+
969
+ User.field :custom, option: true
970
+ end
971
+ end
972
+
973
+ context "when option is nil" do
974
+
975
+ it "calls the handler" do
976
+ handler.should_receive(:call)
977
+ User.field :custom, option: nil
978
+ end
979
+ end
980
+
981
+ context "when option is not provided" do
982
+
983
+ it "does not call the handler" do
984
+ handler.should_receive(:call).never
985
+
986
+ User.field :custom
987
+ end
988
+ end
989
+ end
990
+ end
991
+
992
+ describe "#fields" do
993
+
994
+ context "on parent classes" do
995
+
996
+ let(:shape) do
997
+ Shape.new
998
+ end
999
+
1000
+ it "includes its own fields" do
1001
+ expect(shape.fields.keys).to include("x")
1002
+ end
1003
+
1004
+ it "does not return subclass fields" do
1005
+ expect(shape.fields.keys).to_not include("radius")
1006
+ end
1007
+ end
1008
+
1009
+ context "on subclasses" do
1010
+
1011
+ let(:circle) do
1012
+ Circle.new
1013
+ end
1014
+
1015
+ it "includes the first parent field" do
1016
+ expect(circle.fields.keys).to include("x")
1017
+ end
1018
+
1019
+ it "includes the second parent field" do
1020
+ expect(circle.fields.keys).to include("y")
1021
+ end
1022
+
1023
+ it "includes the child fields" do
1024
+ expect(circle.fields.keys).to include("radius")
1025
+ end
1026
+ end
1027
+ end
1028
+
1029
+ describe ".replace_field" do
1030
+
1031
+ let!(:original) do
1032
+ Person.field(:id_test, type: Moped::BSON::ObjectId, label: "id")
1033
+ end
1034
+
1035
+ let!(:altered) do
1036
+ Person.replace_field("id_test", String)
1037
+ end
1038
+
1039
+ after do
1040
+ Person.fields.delete("id_test")
1041
+ end
1042
+
1043
+ let(:new_field) do
1044
+ Person.fields["id_test"]
1045
+ end
1046
+
1047
+ it "sets the new type on the field" do
1048
+ expect(new_field.type).to eq(String)
1049
+ end
1050
+
1051
+ it "keeps the options from the old field" do
1052
+ expect(new_field.options[:label]).to eq("id")
1053
+ end
1054
+ end
1055
+
1056
+ context "when sending an include of another module at runtime" do
1057
+
1058
+ before do
1059
+ Basic.send(:include, Ownable)
1060
+ end
1061
+
1062
+ context "when the class is a parent" do
1063
+
1064
+ let(:fields) do
1065
+ Basic.fields
1066
+ end
1067
+
1068
+ it "resets the fields" do
1069
+ expect(fields.keys).to include("user_id")
1070
+ end
1071
+ end
1072
+
1073
+ context "when the class is a subclass" do
1074
+
1075
+ let(:fields) do
1076
+ SubBasic.fields
1077
+ end
1078
+
1079
+ it "resets the fields" do
1080
+ expect(fields.keys).to include("user_id")
1081
+ end
1082
+ end
1083
+ end
1084
+
1085
+ context "when a setter accesses a field with a default" do
1086
+
1087
+ let(:person) do
1088
+ Person.new(set_on_map_with_default: "testing")
1089
+ end
1090
+
1091
+ it "sets the default value pre process" do
1092
+ expect(person.map_with_default).to eq({ "key" => "testing" })
1093
+ end
1094
+ end
1095
+
1096
+ context "when a field is defined as a big decimal" do
1097
+
1098
+ let(:band) do
1099
+ Band.new(name: "Tool")
1100
+ end
1101
+
1102
+ let(:decimal) do
1103
+ BigDecimal.new("1000000.00")
1104
+ end
1105
+
1106
+ context "when setting to a big decimal" do
1107
+
1108
+ before do
1109
+ band.sales = decimal
1110
+ end
1111
+
1112
+ it "properly persists as a string" do
1113
+ expect(band.attributes["sales"]).to eq(decimal.to_s)
1114
+ end
1115
+
1116
+ it "returns the proper big decimal" do
1117
+ expect(band.sales).to eq(decimal)
1118
+ end
1119
+ end
1120
+
1121
+ context "when setting to a string" do
1122
+
1123
+ before do
1124
+ band.sales = decimal.to_s
1125
+ end
1126
+
1127
+ it "properly persists as a string" do
1128
+ expect(band.attributes["sales"]).to eq(decimal.to_s)
1129
+ end
1130
+
1131
+ it "returns the proper big decimal" do
1132
+ expect(band.sales).to eq(decimal)
1133
+ end
1134
+ end
1135
+
1136
+ context "when setting to an integer" do
1137
+
1138
+ before do
1139
+ band.sales = decimal.to_i
1140
+ end
1141
+
1142
+ it "properly persists as a string" do
1143
+ expect(band.attributes["sales"]).to eq("1000000")
1144
+ end
1145
+
1146
+ it "returns the proper big decimal" do
1147
+ expect(band.sales).to eq(decimal)
1148
+ end
1149
+ end
1150
+
1151
+ context "when setting to a float" do
1152
+
1153
+ before do
1154
+ band.sales = decimal.to_f
1155
+ end
1156
+
1157
+ it "properly persists as a string" do
1158
+ expect(band.attributes["sales"]).to eq(decimal.to_s)
1159
+ end
1160
+
1161
+ it "returns the proper big decimal" do
1162
+ expect(band.sales).to eq(decimal)
1163
+ end
1164
+ end
1165
+ end
1166
+
1167
+ context "when the field is a hash of arrays" do
1168
+
1169
+ let(:person) do
1170
+ Person.create
1171
+ end
1172
+
1173
+ let(:map) do
1174
+ {
1175
+ "stack1" => [ 1, 2, 3, 4 ],
1176
+ "stack2" => [ 1, 2, 3, 4 ],
1177
+ "stack3" => [ 1, 2, 3, 4 ]
1178
+ }
1179
+ end
1180
+
1181
+ before do
1182
+ person.map = map
1183
+ person.map["stack1"].reverse!
1184
+ person.save
1185
+ end
1186
+
1187
+ it "properly updates the hash" do
1188
+ expect(person.map).to eq(
1189
+ {
1190
+ "stack1" => [ 4, 3, 2, 1 ],
1191
+ "stack2" => [ 1, 2, 3, 4 ],
1192
+ "stack3" => [ 1, 2, 3, 4 ]
1193
+ }
1194
+ )
1195
+ end
1196
+
1197
+ it "persists the changes" do
1198
+ expect(person.reload.map).to eq(
1199
+ {
1200
+ "stack1" => [ 4, 3, 2, 1 ],
1201
+ "stack2" => [ 1, 2, 3, 4 ],
1202
+ "stack3" => [ 1, 2, 3, 4 ]
1203
+ }
1204
+ )
1205
+ end
1206
+ end
1207
+
1208
+ context "when overriding a parent class field" do
1209
+
1210
+ context "when the field has a default value" do
1211
+
1212
+ let!(:canvas) do
1213
+ Canvas.new
1214
+ end
1215
+
1216
+ let!(:test) do
1217
+ Canvas::Test.new
1218
+ end
1219
+
1220
+ it "does not override the parent" do
1221
+ expect(canvas.foo).to eq("original")
1222
+ end
1223
+
1224
+ it "overrides the default" do
1225
+ expect(test.foo).to eq("overridden")
1226
+ end
1227
+ end
1228
+ end
1229
+ end