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